2021.12.19 eleveni的刷题记录
2021.12.19 eleveni的刷题记录
0. 本次记录有意思的题
0.1 每个点恰好经过一次并且求最小时间
P2469 [SDOI2010]星际竞速
https://www.luogu.com.cn/problem/P2469
费用流
0.2 把数字序列转化为01串
AT2165 [AGC006D] Median Pyramid Hard
https://www.luogu.com.cn/problem/AT2165
二分
1. 基础算法
1.1 二分
https://www.luogu.com.cn/problem/AT2165
#include
#include
#include
#include
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int N=2e5+10;
int n,a[N];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline bool check(int maxn){
for(int i=0;imaxn&&a[n-i-1]>maxn)||(a[n+i]>maxn&&a[n+i+1]>maxn))return false;
}
return a[1]<=maxn;
}
signed main(){
IOS;
cin>>n;
for(int i=1;i<=n*2-1;i++)cin>>a[i];
int L=1,R=n*2-1,mid,ans;
while(L>1;
if(check(mid))R=ans=mid;
else L=mid+1;
}
cout<
https://www.luogu.com.cn/problem/P4343
记得把右边界开大!!!!
#include
#include
#include
#include
#include
#include
#include
#define ls (x)<<1
#define rs (x)<<1|1
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
#define int long long
const int N=1e5+10;
int n,m,num[N];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline bool check1(int maxn){
int now=0,cnt=0;
for(int i=1;i<=n;i++){
now+=num[i];
if(now<0)now=0;
if(now>=maxn)++cnt,now=0;
}
return cnt>=m;
}
inline bool check2(int maxn){
int now=0,cnt=0;
for(int i=1;i<=n;i++){
now+=num[i];
if(now<0)now=0;
if(now>=maxn)++cnt,now=0;
}
return cnt<=m;
}
signed main(){
n=read();m=read();
int maxn=-1,minn=0x3f3f3f3f,R1=-1,R2=-1,L1=0,L2=0;
int tot=0;
for(int i=1;i<=n;i++){
num[i]=read();
tot+=num[i];
R1=max(R1,tot);R2=R1;
}
R1=R2=1e14;;
while(L1<=R1){
int mid=(L1+R1)>>1;
//cout<>1;
if(check2(mid))minn=mid,R2=mid-1;
else L2=mid+1;
}
//if(minn==0x3f3f3f3f)return puts("-1"),0;
if(maxn
1.2 贪心
https://www.luogu.com.cn/problem/P4107
#include
#include
#include
#include
#include
#include
#include
#define ls (x)<<1
#define rs (x)<<1|1
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
#define int long long
const int N=2e6+10;
int n,m,cnt,head[N],tmp[N],ans,val[N];
struct node{
int to,next;
}a[N];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline void add(int u,int v){
++cnt;
a[cnt].to=v;
a[cnt].next=head[u];
head[u]=cnt;
}
inline int cmp(int x,int y){
return x
2. 计算几何
2.1 半平面交
如果不知道输入顺序,那么就顺时针逆时针都跑一遍求最大值
#include
#include
#include
#include
#include
using namespace std;
const int N=1e5+10;
const double eps=1e-13;//!
int L,R;
struct node{
double x,y;
inline node operator +(const node &b)const{
return (node){x+b.x,y+b.y};
}
inline node operator -(const node &b)const{
return (node){x-b.x,y-b.y};
}
}stain[N],Cross[N];
inline node operator *(node a,double k){
return (node){a.x*k,a.y*k};
}
inline node operator /(node a,double k){
return (node){a.x/k,a.y/k};
}
inline double cross(node x,node y){
return x.x*y.y-x.y*y.x;
}
inline double dot(node x,node y){
return x.x*y.x+x.y*y.y;
}
struct nodei{
node pos,vec;
double angle;
inline void add(node a,node b){//
pos=a;vec=b;
angle=atan2(b.y,b.x);
}
bool operator <(const nodei &b){
return angle>t;
//while(t--){
int n;cin>>n;
for(int i=n;i>=1;i--)cin>>stain[i].x>>stain[i].y;
for(int i=1;i
3. 图论
3.1 找规律
https://www.luogu.com.cn/problem/P2407
#include
#include
#include
#include
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int N=810;
int n,m,C[N][N],R[N][N];
char a[N][N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%s",a[i]+1);
int aim=0;
for(int j=1;j<=m;j++){
if(a[i][j]=='T')aim^=1;
R[i][j]=aim;
}
}
for(int j=1;j<=m;j++){
int aim=0;
for(int i=1;i<=n;i++){
if(a[i][j]=='T')aim^=1;
C[i][j]=aim;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)putchar('o'),putchar(R[i][j]?45:32);
cout<
3.2 最短路
https://www.luogu.com.cn/problem/P4162
SLF优化SPFA
#include
#include
#include
#include
#include
#include
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int N=35;
const int M=910;
const int inf=0x3f3f3f3f;
int n,m,T,cnt,head[M],start[M],vis[M],cnti[M],dis[M];
double ans,DIS[M][M];
char mapi[N][N];
struct node{
int to,next,val;
}a[M*8];
inline void add(int u,int v,int w){
++cnt;
a[cnt].to=v;
a[cnt].next=head[u];
a[cnt].val=w;
head[u]=cnt;
}
inline int id(int x,int y){
return (x-1)*m+y;
}
inline void spfa(int s){
dequeq;
for(int i=1;i<=n*m;i++)dis[i]=inf,vis[i]=0;
if(start[s])dis[s]=1;else dis[s]=0;
vis[s]=1;
q.push_back(s);
while(!q.empty()){
int x=q.front();q.pop_front();
if(dis[x]<=T)ans=max(ans,DIS[s][x]);
vis[x]=0;
for(int i=head[x];i;i=a[i].next){
int v=a[i].to;
if(dis[v]>dis[x]+a[i].val){
dis[v]=dis[x]+a[i].val;
if(!vis[v]){
vis[v]=1;
if(dis[v]>n>>m>>T;
for(int i=1;i<=n;i++){
scanf("%s",mapi[i]+1);
for(int j=1;j<=m;j++){
int x=id(i,j);
if(mapi[i][j]=='1')start[x]=1;
}
}
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
for(int k=1;k<=n;k++)for(int l=1;l<=m;l++){
int id1=id(i,j),id2=id(k,l);
DIS[id1][id2]=DIS[id2][id1]=(double)sqrt((double)(i-k)*(i-k)+double(j-l)*(j-l));
}
/*cout<<"DIS "<
3.3 Tarjan
https://www.luogu.com.cn/problem/P2469
60pts:
#include
#include
#include
#include
#include
#include
#define ls (x)<<1
#define rs (x)<<1|1
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int N=4e4+10;
const int M=2e5+10;
const int K=6e4+10;
int n,m,cnt,head[N],cnti,headi[N],ans;
int ind,dfn[N],low[N],belong[N],vis[N];
int dfsx,true_id[N],id_true[N],dep[N],top[N],son[N],sizei[N],fa[N];
int val[N<<4],lazy[N<<4];
struct Query{
int op,u,v,ans;
}queryi[K];
struct node{
int to,next,flag;
}a[M],ai[M];
stacks;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline void add(int u,int v){
++cnt;
a[cnt].to=v;
a[cnt].next=head[u];
head[u]=cnt;
}
inline void addi(int u,int v){
++cnti;
ai[cnti].to=v;
ai[cnti].next=headi[u];
headi[u]=cnti;
}
inline void Tarjan(int x,int fai){
dfn[x]=low[x]=++ind;
s.push(x);
for(int i=head[x];i;i=a[i].next){
if(a[i].flag==1)continue;
int v=a[i].to;
if(!dfn[v])Tarjan(v,x),low[x]=min(low[x],low[v]);
else if(dfn[v]>1;
build(ls,l,mid);
build(rs,mid+1,r);
val[x]=val[ls]+val[rs];
}
inline void pushdown(int x){
if(!lazy[x])return ;
lazy[ls]=lazy[rs]=lazy[x];
val[ls]=val[rs]=0;
lazy[x]=0;
}
inline void change(int x,int l,int r,int L,int R){
if(L>r||R=L&&r<=R)return (void)(val[x]=0,lazy[x]=1);
pushdown(x);
int mid=(l+r)>>1;
if(L<=mid)change(ls,l,mid,L,R);
if(R>mid)change(rs,mid+1,r,L,R);
val[x]=val[ls]+val[rs];
}
inline int query(int x,int l,int r,int L,int R){
if(L>r||R=L&&r<=R)return val[x];
pushdown(x);
int mid=(l+r)>>1;
int ans=0;
if(L<=mid)ans+=query(ls,l,mid,L,R);
if(R>mid)ans+=query(rs,mid+1,r,L,R);
val[x]=val[ls]+val[rs];
return ans;
}
inline void dfs1(int x,int fai){
sizei[x]=1;fa[x]=fai;dep[x]=dep[fai]+1;
for(int i=headi[x];i;i=ai[i].next){
int v=ai[i].to;
if(v==fai)continue;
dfs1(v,x);
sizei[x]+=sizei[v];
if(sizei[v]>sizei[son[x]])son[x]=v;
}
}
inline void dfs2(int x,int topi){
top[x]=topi;
true_id[x]=++dfsx;id_true[dfsx]=x;
if(son[x]&&!true_id[son[x]])dfs2(son[x],topi);
for(int i=headi[x];i;i=ai[i].next){
int v=ai[i].to;
if(true_id[v])continue;
if(v==fa[x]||v==son[x])continue;
dfs2(v,v);
}
}
inline void changeline(int x,int y,int flag){
//cout<dep[y])swap(x,y);
if(flag)ans+=query(1,1,dfsx,true_id[x]+1,true_id[y]);
else change(1,1,dfsx,true_id[x]+1,true_id[y]);
//cout<=1;i--){
ans=0;
int ui=belong[queryi[i].u],vi=belong[queryi[i].v];
//cout<
别人100pts:
#include
3.4 网络流
3.4.1 费用流
https://www.luogu.com.cn/problem/P2469
#include
#include
#include
#include
#include
#include
#include
#define ls (x)<<1
#define rs (x)<<1|1
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int N=160010;
const int inf=0x3f3f3f3f;
int n,m,start,endi,cnt=1,head[N];
int maxnflow,maxncost,vis[N],flow[N],pre[N],dis[N];
struct node{
int to,next,val,cost;
}a[N*3];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline void addi(int u,int v,int w,int x){
++cnt;
a[cnt].to=v;
a[cnt].val=w;
a[cnt].cost=x;
a[cnt].next=head[u];
head[u]=cnt;
}
inline void add(int u,int v,int w,int x){
addi(u,v,w,x);addi(v,u,0,-x);
}
inline int spfa(int s,int t){
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
queueq;
dis[s]=0;flow[s]=inf;vis[s]=1;
q.push(s);
while(!q.empty()){
int x=q.front();q.pop();
vis[x]=0;
for(int i=head[x];i;i=a[i].next){
int v=a[i].to;
if(dis[v]>dis[x]+a[i].cost&&a[i].val){
dis[v]=dis[x]+a[i].cost;
flow[v]=min(flow[x],a[i].val);
pre[v]=i;
if(!vis[x])vis[v]=1,q.push(v);
}
}
}
return dis[t]!=inf;
}
inline void update(int s,int t){
int x=t;
while(x!=s){
int xi=pre[x];
a[xi].val-=flow[t];
a[xi^1].val+=flow[t];
x=a[xi^1].to;
}
maxnflow+=flow[t];
maxncost+=flow[t]*dis[t];
}
inline void EK(int s,int t){
while(spfa(s,t))update(s,t);
}
int main(){
n=read();m=read();
start=n*2+1,endi=n*2+2;
for(int i=1;i<=n;i++){
int x=read();
add(start,i,1,0);
add(start,i+n,1,x);
add(i+n,endi,1,0);
}
for(int i=1;i<=m;i++){
int u,v,w;
u=read();v=read();w=read();
if(u>v)swap(u,v);
add(u,v+n,1,w);
}
EK(start,endi);
cout<
4. 数学
4.1 矩阵加速
https://www.luogu.com.cn/problem/P2461
呵呵,输出必须是非负整数!!
20pts:
#include
#include
#include
#include
#include
#include
#include
#define ls (x)<<1
#define rs (x)<<1|1
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
#define int long long
const int N=20;
int n,m,K,mod;
struct Matrix{
int num[N][N];
Matrix(){
memset(num,0,sizeof(num));
}
inline Matrix operator *(const Matrix &b)const{
Matrix c;
for(int i=1;i<=K;i++)
for(int j=1;j<=K;j++)
for(int k=1;k<=K;k++)
c.num[i][j]=(c.num[i][j]+num[i][k]*b.num[k][j]%mod)%mod;
return c;
}
}ans,basic;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline Matrix operator ^(Matrix x,int y){
Matrix fin=x;--y;
while(y){
if(y&1)fin=fin*x;
x=x*x;
y>>=1;
}
return fin;
}
signed main(){
K=read();
for(int i=1;i<=K;i++)ans.num[i][1]=read();
for(int i=K;i>=1;i--){
if(i0)ans=(basic^(m-K))*ans;
//cout<<"ans "<
100pts:
#include
#include
#include
#include
#include
#include
#include
#define ls (x)<<1
#define rs (x)<<1|1
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
#define int long long
const int N=20;
int n,m,K,mod,sum[N];
struct Matrix{
int num[N][N];
Matrix(){
memset(num,0,sizeof(num));
}
inline Matrix operator *(const Matrix &b)const{
Matrix c;
for(int i=1;i<=K+1;i++)
for(int j=1;j<=K+1;j++)
for(int k=1;k<=K+1;k++)
c.num[i][j]=(c.num[i][j]+num[i][k]*b.num[k][j]%mod)%mod;
return c;
}
}ans,basic;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline Matrix operator ^(Matrix x,int y){
Matrix fin;
if(y==0)return fin;
fin=x;--y;
while(y>0){
if(y&1)fin=fin*x;
x=x*x;
y>>=1;
}
return fin;
}
signed main(){
K=read();
for(int i=1;i<=K;i++)ans.num[i][1]=read();
for(int i=K;i>=1;i--){
if(i
5. 动态规划
5.1 贪心优化
https://www.luogu.com.cn/problem/P2577
这个看似可以记忆化搜索。
#include
#include
#include
#include
#include
#include
#include
#define ls (x)<<1
#define rs (x)<<1|1
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int N=210;
const int inf=0x3f3f3f3f;
int n,f[N][N*N],sum[N];
struct node{
int wait,eat;
bool operator <(const node &b)const{
return eat>b.eat;
}
}a[N];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
int main(){
n=read();
for(int i=1;i<=n;i++)a[i].wait=read(),a[i].eat=read();
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i].wait;
memset(f,inf,sizeof(f));
f[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=sum[i];j++){
if(j>=a[i].wait)f[i][j]=min(f[i][j],max(f[i-1][j-a[i].wait],j+a[i].eat));
f[i][j]=min(f[i][j],max(f[i-1][j],sum[i]-j+a[i].eat));
}
int ans=inf;
for(int i=0;i<=sum[n];i++)ans=min(ans,f[n][i]);
cout<