一期极逊 总结
rt.
7.15
晚上 6:00 到校。预习网络流并打了板子。
7.16
树上启发式合并。
7.17
二项式反演、min-max 容斥。
简单二项式反演练习题。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=2e3+5,mod=998244353;
int f[N+10],g[N+10];
int ksm(int x,int p)
{
int ans=1;
while(p)
{
if(p&1) ans*=x,ans%=mod;
x*=x;
x%=mod;
p>>=1;
}
return ans;
}
int C(int n,int m) { return f[n]*g[m]%mod*g[n-m]%mod; }
int A(int n,int m) { return f[n]*g[n-m]%mod; }
int ans1[N+10][N+10],ans2[N+10];
int n;
void solve()
{
cin>>n;
for(int i=0;i<=n;i++)
{
cout<<((f[n]*f[n]%mod*ksm(2,i)%mod*g[i]%mod*ans1[n-i][n-i]%mod)+mod)%mod<<"\n";
}
}
signed main()
{
f[0]=g[0]=1;
for(int i=1;i<=N;i++)
{
f[i]=f[i-1]*i%mod;
g[i]=g[i-1]*ksm(i,mod-2)%mod;
}
for(int up=0;up<=N;up++)
for(int k=0;k<=N;k++)
{
if(up-k<0) continue;
ans1[up][k]=ksm(-2,k)*f[up*2-k*2]%mod*g[k]%mod*g[up-k]%mod*g[up-k]%mod;
}
for(int up=0;up<=N;up++)
for(int k=1;k<=N;k++)
{
if(up-k<0) continue;
ans1[up][k]+=ans1[up][k-1];
ans1[up][k]%=mod;
}
int T;
cin>>T;
while(T--) solve();
//mt19937_64 myrand(time(0));
return 0;
}
/*
722842020
138317470
921559819
359647162
687141626
346118686
625222092
542337323
886269899
944317174
460589718
811540952
20786512
387585883
469474953
548906529
871917136
778406107
569092611
800860
337514426
801633802
312159821
93444031
90542578
825940975
20000024
785199061
994585930
350128415
862900103
883162129
629959277
739204290
608293632
540950158
124289136
363286358
857308713
384746793
879153927
556173190
857677375
450955017
531591432
982819172
933001092
512595394
933070829
778961352
480009603
935286090
105123621
516375897
160958344
204402744
637758029
908640277
787972008
445923251
492507983
985429386
29082706
94289639
34604091
711283065
939587034
126262080
669499437
878972708
514361506
937924966
291237852
663298724
343816962
638919380
172534971
236170058
706172886
424787480
245248445
723990161
640745596
366740992
355944213
91835749
762422232
498310831
523709105
952955025
758565254
813416457
223906298
527918435
873083460
700091485
275169024
813932544
367384406
98485087
255154139
291410572
875700873
575067313
225892744
728391529
382628520
430033891
424258091
681971977
309495248
900585846
444259669
144328395
497755102
105359049
414357189
501715013
164613658
223170445
595298490
422835443
593597720
875654288
284387774
489562371
482264304
238514139
782091429
164339473
863532562
866250331
643349175
878646607
738273646
27863113
411315395
439803440
782881118
218418857
609619595
724811521
78633262
207988400
504696797
972193769
457708548
940592292
45742516
286866804
79443616
241157958
629915495
804238514
609548941
876247363
338354111
235891198
76205581
784179371
882966638
692354778
857926608
767375468
241164071
494388844
32769290
80892207
627156221
765688243
78524214
519630931
319011152
98684160
305160774
116478813
960434372
112669762
458641843
378309944
870208877
161585052
638364192
641094443
34192556
292431309
855793216
406164415
779379568
167904527
76458518
450512519
387093597
515624040
689883306
820096400
769832610
764317094
534074955
343150200
884048630
418840080
339348891
420417480
265388714
955231917
584293377
168817667
284226287
306777235
146035273
710214882
137785837
130407642
214592951
506563950
503410027
126477417
643999908
642785186
986853015
370695720
852860359
962946253
430988776
791048346
69543110
178854306
183142415
589674406
599255805
15174494
825164427
78990849
842232350
430597019
432697055
406619683
486926560
701430448
433984620
548568248
844174810
570957603
177800111
13377421
78401592
286853293
939821381
509288814
430953495
249086281
720976054
799266140
736711201
418258741
254956950
306035317
599715097
752070223
776986725
689180513
16742228
480771114
2927903
445260862
157011363
225336428
477455530
211970956
49179733
748627454
519167637
377372573
725662056
255023909
128593679
465290478
178234348
186912204
750214431
733907416
602138568
972271415
823746778
684973983
234639199
352049987
654813174
720489232
859900739
406591055
454869456
0
918846203
722842020
138317470
987752262
359647162
687141626
346118686
625222092
542337323
886269899
944317174
460589718
811540952
20786512
387585883
469474953
548906529
871917136
778406107
569092611
800860
337514426
801633802
312159821
93444031
90542578
825940975
20000024
785199061
994585930
350128415
862900103
883162129
629959277
739204290
608293632
540950158
124289136
363286358
857308713
384746793
879153927
556173190
857677375
450955017
531591432
982819172
933001092
512595394
933070829
778961352
480009603
935286090
105123621
516375897
160958344
204402744
637758029
908640277
787972008
445923251
492507983
985429386
29082706
94289639
34604091
711283065
939587034
126262080
669499437
878972708
514361506
937924966
291237852
663298724
343816962
638919380
172534971
236170058
706172886
424787480
245248445
723990161
640745596
366740992
355944213
91835749
762422232
498310831
523709105
952955025
758565254
813416457
223906298
527918435
873083460
700091485
275169024
813932544
367384406
98485087
255154139
291410572
875700873
575067313
225892744
728391529
382628520
430033891
424258091
681971977
309495248
900585846
444259669
144328395
497755102
105359049
414357189
501715013
164613658
223170445
595298490
422835443
593597720
875654288
284387774
489562371
482264304
238514139
782091429
164339473
863532562
866250331
643349175
878646607
738273646
27863113
411315395
439803440
782881118
218418857
609619595
724811521
78633262
207988400
504696797
972193769
457708548
940592292
45742516
286866804
79443616
241157958
629915495
804238514
609548941
876247363
338354111
235891198
76205581
784179371
882966638
692354778
857926608
767375468
241164071
494388844
32769290
80892207
627156221
765688243
78524214
519630931
319011152
98684160
305160774
116478813
960434372
112669762
458641843
378309944
870208877
161585052
638364192
641094443
34192556
292431309
855793216
406164415
779379568
167904527
76458518
450512519
387093597
515624040
689883306
820096400
769832610
764317094
534074955
343150200
884048630
418840080
339348891
420417480
265388714
955231917
584293377
168817667
284226287
306777235
146035273
710214882
137785837
130407642
214592951
506563950
503410027
126477417
643999908
642785186
986853015
370695720
852860359
962946253
430988776
791048346
69543110
178854306
183142415
589674406
599255805
15174494
825164427
78990849
842232350
430597019
432697055
406619683
486926560
701430448
433984620
548568248
844174810
570957603
177800111
13377421
78401592
286853293
939821381
509288814
430953495
249086281
720976054
799266140
736711201
418258741
254956950
306035317
599715097
752070223
776986725
689180513
16742228
480771114
2927903
445260862
157011363
225336428
477455530
211970956
49179733
748627454
519167637
377372573
725662056
255023909
128593679
465290478
178234348
186912204
750214431
733907416
602138568
972271415
823746778
684973983
234639199
352049987
654813174
720489232
859900739
406591055
454869456
0
918846203
*/
7.18
可持久化线段树、平衡树、字典树。
区间修改可持久化线段树板子。
代码只可持久化了懒标记。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,m;
int a[N],f[N];
// dt: ;子树里的 add 总和
// lazy : 该区间懒标记
struct Tree{
int dt,lazy;
int lp,rp;
}t[N*500];//n log_n log_(n log_n)
int tot;
int root[N];
int add(int l,int r,int sl,int sr,int k,int lastp,int &nwp)
{
if(!nwp) nwp=++tot;
if(sl<=l&&r<=sr)
{
t[nwp]={t[lastp].dt+k*(r-l+1),t[lastp].lazy+k,t[lastp].lp,t[lastp].rp};
// cerr<<l<<" "<<r<<" "<<sl<<" "<<sr<<" k="<<k<<" len="<<r-l+1<<" ";
// cerr<<"t[nwp].lazy="<<t[nwp].lazy<<" t[nwp].dt="<<t[nwp].dt<<" ";
// cerr<<"t[lastp].lazy="<<t[lastp].lazy<<" t[lastp].dt="<<t[lastp].dt<<"\n";
return k*(r-l+1);
}
int mid=(l+r)>>1,dt=0;
if(sl<=mid) dt=add(l,mid,sl,sr,k,t[lastp].lp,t[nwp].lp);
else t[nwp].lp=t[lastp].lp;
if(sr>mid) dt+=add(mid+1,r,sl,sr,k,t[lastp].rp,t[nwp].rp);
else t[nwp].rp=t[lastp].rp;
t[nwp].lazy=t[lastp].lazy;
t[nwp].dt=t[lastp].dt+dt;
// cerr<<l<<" "<<r<<" "<<sl<<" "<<sr<<" ";
// cerr<<"t[nwp].lazy="<<t[nwp].lazy<<" t[nwp].dt="<<t[nwp].dt<<"\n";
return dt;
}
// pair<int,int> operator+(const pair<int,int> &x,const pair<int,int> &y)
// {
// pair<int,int> ans=make_pair(0,0);
// ans.first=x.first+y.first;
// ans.second=x.second+y.second;
// return ans;
// }
int find(int l,int r,int sl,int sr,int nw_lazy,int p)
{
if(sl<=l&&r<=sr)
{
// cout<<"l="<<l<<" r="<<r<<" sl="<<sl<<" sr="<<sr<<" dt="<<t[p].dt<<" lazy="<<nw_lazy*(r-l+1)<<"\n";
return t[p].dt+nw_lazy*(r-l+1);
}
int mid=(l+r)>>1,ans=0;
if(sl<=mid) ans+=find(l,mid,sl,sr,nw_lazy+t[p].lazy,t[p].lp);
if(sr>mid) ans+=find(mid+1,r,sl,sr,nw_lazy+t[p].lazy,t[p].rp);
// cout<<"l="<<l<<" r="<<r<<" sl="<<sl<<" sr="<<sr<<" ans="<<ans<<"\n";
return ans;
// pair<int,int> ans=make_pair(0,0);
}
int query(int l,int r,int t)
{
// cout<<root[t]<<"\n";
return find(1,n,l,r,0,root[t]);
}
signed main()
{
// freopen("a.in","r",stdin);
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],f[i]=f[i-1]+a[i];
// return 0;
int nw=0;
while(m--)
{
char op;
int l,r,d,t;
cin>>op;
if(op=='C')
{
cin>>l>>r>>d;
nw++;
add(1,n,l,r,d,root[nw-1],root[nw]);
}
if(op=='Q')
{
cin>>l>>r;
cout<<query(l,r,nw)+f[r]-f[l-1]<<"\n";
}
if(op=='H')
{
cin>>l>>r>>t;
cout<<query(l,r,t)+f[r]-f[l-1]<<"\n";
}
if(op=='B')
{
cin>>t;
for(int j=t+1;j<=nw;j++) root[j]=0;
nw=t;
}
}
//mt19937_64 myrand(time(0));
return 0;
}
/*
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
*/
简单可持久化字典树应用。
写了四个二分。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
bool num[50100][36];
int n;
int a[50100];
int st[17][50100];
int logn[50100];
int ksm[65]={};
int root[50100];
int tot;
struct Tree{
int lp,rp,cnt;
}t[50100*34*2];
void add(int id,int pos,int lastp,int &p)
{
if(pos>34) return;
if(!p) p=++tot;
t[p].cnt=t[lastp].cnt+1;
if(num[id][pos+1]==0)
{
add(id,pos+1,t[lastp].lp,t[p].lp);
t[p].rp=t[lastp].rp;
}
else
{
add(id,pos+1,t[lastp].rp,t[p].rp);
t[p].lp=t[lastp].lp;
}
// t[p].cnt=t[t[p].lp].cnt+t[t[p].rp].cnt;
}
void chai(int id)
{
int cnt=0,x=a[id];
while(x)
{
// cerr<<"cnt="<<cnt<<"\n";
num[id][++cnt]=(x&1);
x>>=1;
}
for(int i=34,j=1;i>j;i--,j++) swap(num[id][j],num[id][i]);
add(id,0,root[id-1],root[id]);
}
int query(int l,int r)
{
int k=logn[r-l+1];
return max(st[k][l],st[k][r-(1<<k)+1]);
}
int xorrr(int id,int lp,int rp,long long dt)
{
int ans=0;
// if(pos>34) return 0;
for(int pos=1;pos<=34;pos++)
{
int c[2]={};
c[0]=t[t[rp].lp].cnt-t[t[lp].lp].cnt;
c[1]=t[t[rp].rp].cnt-t[t[lp].rp].cnt;
if(c[1^num[id][pos]])
{
// cout<<(1^num[id][pos]);
ans+=dt;
if(num[id][pos]==0) lp=t[lp].rp,rp=t[rp].rp;
else lp=t[lp].lp,rp=t[rp].lp;
}
else if(num[id][pos]==0) lp=t[lp].lp,rp=t[rp].lp;//,cout<<num[id][pos];
else lp=t[lp].rp,rp=t[rp].rp;//,cout<<num[id][pos];
dt>>=1;
}
// cout<<"\n";
return ans;
// int lp=t[t[nwp].lp].cnt,rp=;
}
int find(int nw_p)
{
int pl1=nw_p-1;
// if(pl1>=1)
for(int k=logn[pl1];k>=0;k--)
if(pl1-ksm[k]>0&&query(pl1-ksm[k],pl1)<a[nw_p]) pl1-=ksm[k];
if(a[pl1]>=a[nw_p]||pl1<1) pl1++;
int pr1=nw_p+1;
if(pr1<=n)
for(int k=logn[n-nw_p];k>=0;k--)
if(pr1+ksm[k]<=n&&query(pr1,pr1+ksm[k])<a[nw_p]) pr1+=ksm[k];
if(a[pr1]>=a[nw_p]||pr1>n) pr1--;
// cout<<"pl1="<<pl1<<" pr1="<<pr1<<"\n";
int ans=0;
if(pl1>1)
{
int pl2=pl1-2;
if(pl2>0&&a[pl2]<a[nw_p])
{
for(int k=logn[pl2];k>=0;k--)
if(pl2-ksm[k]>0&&query(pl2-ksm[k],pl2)<a[nw_p]) pl2-=ksm[k];
}
else pl2++;
// cout<<"left ["<<pl2<<","<<pr1<<"] nw="<<nw_p<<"\n";
ans=xorrr(nw_p,root[pl2-1],root[pr1],ksm[33]);
}
if(pr1<n)
{
int pr2=pr1+2;
if(pr2<=n&&a[pr2]<a[nw_p])
{
for(int k=logn[n-pr2+1];k>=0;k--)
if(pr2+ksm[k]<=n&&query(pr2,pr2+ksm[k])<a[nw_p]) pr2+=ksm[k];
}
else pr2--;
// cout<<"right ["<<pl1<<","<<pr2<<"] nw="<<nw_p<<"\n";
ans=max(ans,xorrr(nw_p,root[pl1-1],root[pr2],ksm[33]));
}
return ans;
// p--;
// a_i \belongs [p,l), a_i< a_r
}
signed main()
{
n=read();
for(int i=1;i<=n;i++) a[i]=read(),st[0][i]=a[i];
logn[1]=0;
ksm[0]=1;
for(int i=1;i<=40;i++) ksm[i]=ksm[i-1]<<1;
for(int i=2;i<=n+10;i++) logn[i]=logn[i>>1]+1;
for(int j=1;j<=logn[n];j++)
for(int i=1;i<=n;i++)
st[j][i]=max(st[j-1][i],st[j-1][i+(1<<(j-1))]);
for(int i=1;i<=n;i++) chai(i);
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,find(i));
cout<<ans;
return 0;
}
纯板子。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=9e5+10;
bool num[N][36];
int n;
int a[N];
int st[17][N];
int logn[N];
int ksm[65]={};
int root[N];
int tot;
struct Tree{
int lp,rp,cnt;
}t[N*30*3];
// int sum[1<<20];
void add(int id,int pos,int lastp,int &p)
{
if(pos>30) return;
if(!p) p=++tot;
t[p].cnt=t[lastp].cnt+1;
if(num[id][pos+1]==0)
{
add(id,pos+1,t[lastp].lp,t[p].lp);
t[p].rp=t[lastp].rp;
}
else
{
add(id,pos+1,t[lastp].rp,t[p].rp);
t[p].lp=t[lastp].lp;
}
// t[p].cnt=t[t[p].lp].cnt+t[t[p].rp].cnt;
}
void chai(int id)
{
int cnt=0;
int x=a[id];
while(x)
{
num[id][++cnt]=(x&1);
x>>=1;
}
for(int i=30,j=1;i>j;i--,j++) swap(num[id][j],num[id][i]);
}
int xorrr(int id,int lp,int rp,long long dt)
{
int ans=0;
// if(pos>30) return 0;
for(int pos=1;pos<=30;pos++)
{
int c[2]={};
// cout<<"lp="<<lp<<" rp="<<rp<<"\n";
c[0]=t[t[rp].lp].cnt-t[t[lp].lp].cnt;
c[1]=t[t[rp].rp].cnt-t[t[lp].rp].cnt;
// cout<<"pos="<<pos<<" c[0]="<<c[0]<<" c[1]="<<c[1]<<"\n";
if(c[1^num[id][pos]])
{
// cout<<1;
ans+=dt;
if(num[id][pos]==0) lp=t[lp].rp,rp=t[rp].rp;
else lp=t[lp].lp,rp=t[rp].lp;
}
else if(num[id][pos]==0) lp=t[lp].lp,rp=t[rp].lp;//,cout<<0;
else lp=t[lp].rp,rp=t[rp].rp;//,cout<<0;
dt>>=1;
}
// cout<<"\n";
return ans;
// int lp=t[t[nwp].lp].cnt,rp=;
}
// int find(int nw_p)
// {
// int pl1=nw_p-1;
// // if(pl1>=1)
// for(int k=logn[pl1];k>=0;k--)
// if(pl1-ksm[k]>0&&query(pl1-ksm[k],pl1)<a[nw_p]) pl1-=ksm[k];
// if(a[pl1]>=a[nw_p]||pl1<1) pl1++;
// int pr1=nw_p+1;
// if(pr1<=n)
// for(int k=logn[n-nw_p];k>=0;k--)
// if(pr1+ksm[k]<=n&&query(pr1,pr1+ksm[k])<a[nw_p]) pr1+=ksm[k];
// if(a[pr1]>=a[nw_p]||pr1>n) pr1--;
// // cout<<"pl1="<<pl1<<" pr1="<<pr1<<"\n";
// int ans=0;
// if(pl1>1)
// {
// int pl2=pl1-2;
// if(pl2>0&&a[pl2]<a[nw_p])
// {
// for(int k=logn[pl2];k>=0;k--)
// if(pl2-ksm[k]>0&&query(pl2-ksm[k],pl2)<a[nw_p]) pl2-=ksm[k];
// }
// else pl2++;
// // cout<<"left ["<<pl2<<","<<pr1<<"] nw="<<nw_p<<"\n";
// ans=xorrr(nw_p,root[pl2-1],root[pr1],ksm[33]);
// }
// if(pr1<n)
// {
// int pr2=pr1+2;
// if(pr2<=n&&a[pr2]<a[nw_p])
// {
// for(int k=logn[n-pr2+1];k>=0;k--)
// if(pr2+ksm[k]<=n&&query(pr2,pr2+ksm[k])<a[nw_p]) pr2+=ksm[k];
// }
// else pr2--;
// // cout<<"right ["<<pl1<<","<<pr2<<"] nw="<<nw_p<<"\n";
// ans=max(ans,xorrr(nw_p,root[pl1-1],root[pr2],ksm[33]));
// }
// return ans;
// // p--;
// // a_i \belongs [p,l), a_i< a_r
// }
signed main()
{
int n,m,tot=6e5;
n=read();
m=read();
ksm[0]=1;
for(int i=1;i<=40;i++) ksm[i]=ksm[i-1]*2;
add(0,0,0,root[0]);
for(int i=1;i<=n;i++) a[i]=read()^a[i-1],chai(i),add(i,0,root[i-1],root[i]);//;,cout<<a[i]<<"\n";
while(m--)
{
char op;
cin>>op;
if(op=='A')
{
int x=read();
n++;
a[n]=x^a[n-1];
chai(n);
add(n,0,root[n-1],root[n]);
}
else
{
int l=read(),r=read(),x=read()^a[n];
a[++tot]=x;
chai(tot);
// cout<<"["<<l-1<<","<<r-1<<"]\n";
// cout<<x<<"\n";
cout<<xorrr(tot,root[l-2],root[r-1],ksm[29])<<"\n";
}
}
return 0;
}
单 \(\log\) 的败北,两只 \(\log\) 的胜利!
~~两只 log,两只 log,跑得快,跑得快~ ~~
由于倍增二分天然满足 01 串试填法的性质,故通过奇淫技巧可以砍掉半只 \(\log\),奋战 \(5h\) 终于过了。
点击查看代码
#include<bits/stdc++.h>
// #define int long long
// #define int unsigned int
using namespace std;
inline int read()
{
int x=0,c=getchar_unlocked(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar_unlocked());
for(;c>='0'&&c<='9';c=getchar_unlocked())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar_unlocked('-');
if(x>9) write(x/10);
putchar_unlocked(x%10+'0');
}
const int N=3e5+10;
bitset<36> num[N];
int n;
int y[N],x[1<<20];
int ksm[65]={};
signed root[N];
int tot;
struct Tree{
signed lp,rp;
int cnt;
}t[310000*31];
// int sum[1<<20];
void add(int id,int pos,signed lastp,signed &p)
{
if(pos>31) return;
if(!p) p=++tot;
t[p].cnt=t[lastp].cnt+1;
// cout<<"pos="<<pos<<" cnt="<<t[p].cnt<<"\n";
// cout<<num[id][pos];
if(num[id][pos+1]==0)
{
add(id,pos+1,t[lastp].lp,t[p].lp);
t[p].rp=t[lastp].rp;
}
else
{
add(id,pos+1,t[lastp].rp,t[p].rp);
t[p].lp=t[lastp].lp;
}
}
void chai(int x,int id)
{
num[id]=0;
// memset(num[id],0,sizeof(num[id]));
int cnt=0;
while(x)
{
// cerr<<x<<"\n";
num[id][++cnt]=(x&1);
x>>=1;
}
for(int i=31,j=1;i>j;i--,j++)
{
int nw=num[id][j];
num[id][j]=num[id][i];
num[id][i]=nw;
}
}
int nxtl[1005],nxtr[1005];
pair<int,int> xorrr(int id,int s,int lp,int rp,long long dt,bool f)
{
int ans=0,ans2=0;
for(int pos=s;pos<=31;pos++)
{
int c[2]={};
// cout<<lp<<" "<<rp<<"\n";
if(lp==0&&rp==0) break;
if(f&&pos!=s) break;
c[0]=t[t[rp].lp].cnt-t[t[lp].lp].cnt;
c[1]=t[t[rp].rp].cnt-t[t[lp].rp].cnt;
if(num[id][pos]==0)
{
if(num[0][pos]==0) lp=t[lp].lp,rp=t[rp].lp;
else
{
ans+=c[0];
ans2+=(s==pos)*c[0];
lp=t[lp].rp,rp=t[rp].rp;
}
}
else
{
if(num[0][pos]==0) lp=t[lp].rp,rp=t[rp].rp;
else
{
ans+=c[1];
ans2+=(s==pos)*c[1];
// cout<<"c[0]="<<c[0]<<" c[1]="<<c[1]<<"\n";
// cout<<"pos="<<pos<<" ";
lp=t[lp].lp,rp=t[rp].lp;
}
}
// dt>>=1;
}
// cout<<"\n\n\n";
// for(int pos=1;pos<=31;pos++)
// cout<<num[0][pos]<<"";
// cout<<"\n";
// for(int pos=1;pos<=31;pos++)
// cout<<num[id][pos]<<"";
// cout<<"\n";
return make_pair(ans,ans2);
}
pair<int,int> check(int i,int s,int l,int r,bool f)
{
// cout<<"["<<l<<","<<r<<"]\n";
// return xorrr(i,1,root[l-1],root[r],ksm[31]);
return xorrr(i,s,nxtl[i],nxtr[i],ksm[31],f);
}
// int x[1<<20],y[1];
// int ksm[105];
signed main()
{
int n,m;
n=read();
m=read();
ksm[0]=1;
for(int i=1;i<=40;i++) ksm[i]=ksm[i-1]*2;
for(int i=1;i<=n;i++) x[i]=read();
add(0,0,0,root[0]);
// cout<<"\n";
for(int i=1;i<=m;i++) y[0]=read(),chai(y[0],0),add(0,0,root[i-1],root[i]);//;,cout<<y[i]<<"\n";
// cout<<"\n";
// memset(num[0],0,sizeof(num[0]));
for(int i=1;i<=n;i++) chai(x[i],i);
int p=read();
while(p--)
{
int u=read(),d=read(),l=read(),r=read(),kth=(r-l+1)*(d-u+1)-read()+1;
int MAXN=31,nw=0;
int rl=root[l-1],rr=root[r];
num[0]=0;
// nxtl=root[l-1],nxtr=root[r];
for(int i=u;i<=d;i++) nxtl[i]=root[l-1],nxtr[i]=root[r];
// memset(num[0],0,sizeof(num[0]));
for(int k=30,j=1;k>=0;k--,j++)
{
// cout<<"k="<<k<<" kth="<<kth<<"\n";
int cnt=0,cnt2=0;
y[0]=nw+ksm[k];
// chai(y[0],0);
num[0][j]=1;
bool f=0;
for(int i=u;i<=d;i++)
{
if(k!=30)
{
if(num[i][j-1]==0)
{
if(num[0][j-1]==0) nxtl[i]=t[nxtl[i]].lp,nxtr[i]=t[nxtr[i]].lp;
else nxtl[i]=t[nxtl[i]].rp,nxtr[i]=t[nxtr[i]].rp;
}
else
{
if(num[0][j-1]==0) nxtl[i]=t[nxtl[i]].rp,nxtr[i]=t[nxtr[i]].rp;
else nxtl[i]=t[nxtl[i]].lp,nxtr[i]=t[nxtr[i]].lp;
}
}
pair<int,int> ccc=check(i,j,l,r,f);
cnt+=ccc.first;
cnt2+=ccc.second;
// cout<<"\n";
if(cnt>=kth) f=1;
if(cnt+(d-i)*(r-l+1)<kth) f=1;
}
if(cnt<kth) nw+=ksm[k],kth-=cnt2;
else num[0][j]=0;
}
// cout<<nw<<"\n";
write(nw);
putchar('\n');
root[l-1]=rl;
root[r]=rr;
}
return 0;
}
大力分块!
借鉴 KinNa_Sky 的思路。
分块,并精细实现预处理,跑到了最优解。
点击查看代码
#include<stdio.h>
inline int read()
{
int l=0,c=getchar_unlocked();
for(;c>'9'||c<'0';c=getchar_unlocked());
for(;c>='0'&&c<='9';c=getchar_unlocked())
l=(l<<1)+(l<<3)+(c^48);
return l;
}
inline void write(int l)
{
if(l>9) write(l/10);
putchar_unlocked(l%10+'0');
}
int n,m;
int sum[12001];
const int len=100;
int ma1[12001][12001/len+3];
int ma2[12001][12001/len+3];
int ma3[12001/len+3][12001/len+3];
short id[12001];
inline int max(int x,int y) { return x>y?x:y; }
signed main()
{
register int lastans=0,l,r,maxn,i,j,x,y;
for( i=1;i<=12000;i++) id[i]=i/len+1;
n=read();
m=read();
for( i=1;i<=n;i++) sum[i]=sum[i-1]^read();
for( l=1;l<=n;l++)
{
maxn=0;
for( r=l;r<=n;r++)
{
maxn=max(maxn,sum[r]^sum[l-1]);
ma1[l][id[r]]=max(maxn,ma1[l][id[r]]);
ma2[r][id[l]]=max(ma2[r][id[l]],maxn);
ma3[id[l]][id[r]]=max(maxn,ma3[id[l]][id[r]]);
}
}
for( i=1;i<=id[n];i++)
for( j=i;j<=id[n];j++)
for( x=i;x<=j;x++)
for( y=x;y<=j;y++)
ma3[i][j]=max(ma3[i][j],ma3[x][y]);
for( i=1;i<=n;i++)
for( j=id[i]+1;j<=id[n];j++)
ma1[i][j]=max(ma1[i][j],ma1[i][j-1]);
for( i=1;i<=n;i++)
for( j=id[i]-1;j>0;j--)
ma2[i][j]=max(ma2[i][j],ma2[i][j+1]);
while(m--)
{
l=read()%n+lastans%n,r=read()%n+lastans%n;
l%=n,r%=n;
l++;r++;
if(l>r) l^=r^=l^=r;
lastans=ma3[id[l]+1][id[r]-1];
// cout<<l<<" "<<r<<"\n";
if(id[l]==id[r])
{
maxn=0;
for(i=l;i<=r;i++)
for(j=i;j<=r;j++)
maxn=max(maxn,sum[j]^sum[i-1]);
lastans=maxn;
write(maxn);
putchar_unlocked('\n');
continue;
}
for(i=l;i<=id[l]*len-1;i++) lastans=max(lastans,ma1[i][id[r]-1]);
for(i=(id[r]-1)*len;i<=r;i++) lastans=max(lastans,ma2[i][id[l]+1]);
// cout<<"l="<<l<<" id[l]*len-1="<<id[l]*len-1<<" (id[r]-1)*len="<<(id[r]-1)*len<<" r="<<r<<"\n";
for(i=l;i<=id[l]*len-1;i++)
for(j=(id[r]-1)*len;j<=r;j++)
{
// cout<<"j="<<j<<" i="<<i<<"\n";
lastans=max(lastans,sum[j]^sum[i-1]);
}
// for(int l=l;l<=r;l++)
// {
// int len=r-l;
// // cout<<"l="<<l<<" len="<<len<<"\n";
// lastans=max(lastans,v[l][len]);
// }
// cout<<lastans<<"\n";
write(lastans);
putchar('\n');
}
// add(0,0,0,root[0]);
// for(int i=1;i<=n;i++) a[i]=read(),chai(a[i],i),add(i,0,root[i-1],root[i]);
// for(int i=1;i<=n;i++)
return 0;
}
/*
113 4788
1073741731
2645 4761
*/
7.20
园方树。
园方树板子题。
点击查看代码
#include<bits/stdc++.h>
// #define int long long
using namespace std;
int n,m;
vector<int> E[1<<22],G[1<<22];
int dcc_cnt;
int pre[1<<22];
int dfn[1<<22],low[1<<22],tot;
int sta[1<<22],top;
void tarjan(int u,int fa)
{
dfn[u]=low[u]=++tot;
sta[++top]=u;
for(int to:G[u])
{
if(fa==to) continue;
if(!dfn[to])
{
tarjan(to,u);
low[u]=min(low[u],low[to]);
if(low[to]>=dfn[u])
{
++dcc_cnt;
E[u].push_back(dcc_cnt+n);
// while(sta[top]!=to)
// for(;;)
while(1)
{
int x=sta[top--];
E[dcc_cnt+n].push_back(x);
if(x==to) break;
}
// while(sta[--top]!=to)
}
}
else low[u]=min(low[u],dfn[to]);
}
}
int fa[1<<22],dep[1<<22];
int idx[1<<22];
int st[22][1<<22];
short logn[1<<22];
void dfs(int u)
{
pre[u]=pre[fa[u]]+(u<=n);
idx[u]=++tot;
st[0][idx[u]]=u;
for(auto to:E[u])
{
fa[to]=u;
dep[to]=dep[u]+1;
dfs(to);
}
}
inline int Min(int u,int v) { return dep[u]<dep[v]?u:v; }
int lca(int u,int v)
{
if(u==v) return v;
if((u=idx[u])>(v=idx[v])) swap(u,v);
int k=logn[v-u];
u++;
// cout<<"k="<<k<<" "<<st[k][u]<<" "<<st[k][v-(1<<k)+1]<<"\n";
return fa[Min(st[k][u],st[k][v-(1<<k)+1])];
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("P4320.out","w",stdout);
#endif
for(int i=2;i<(1<<22);i++) logn[i]=logn[i>>1]+1;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
tarjan(1,0);
// cerr<<"tot="<<tot<<"\n";
tot=0;
dfs(1);
// cerr<<"tot="<<tot<<"\n";
for(int k=1;k<=logn[tot];k++)
for(int i=1;i+(1<<k)-1<=tot;i++)
st[k][i]=Min(st[k-1][i],st[k-1][i+(1<<(k-1))]);
// for (int k = 1; k <=logn[n]; ++k)
// for (int i = 1; i + (1 << k) - 1 <= tot; ++i)
// st[k][i] = Min(st[k - 1][i], st[k - 1][i + (1 << (k - 1))]);
int q;
cin>>q;
while(q--)
{
int u,v;
cin>>u>>v;
int p=lca(u,v);
// cout<<"u="<<u<<" v="<<v<<" p="<<p<<" \n";
cout<<pre[u]+pre[v]-pre[p]-pre[fa[p]]<<"\n";
}
return 0;
}
7.22
杂题。
人类智慧做法,不展开了。
具体思想是拆贡献。
点击查看代码
#include<bits/stdc++.h>
#define int __int128
// #define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n;
struct Node{
int l,r;
}a[1<<20];
bool cmp1(Node x,Node y) { return x.l==y.l?x.r<y.r:x.l<y.l; }
// bool cmp2(Node x,Node y) { return x.r==y.r?x.l<y.l:x.r<y.r; }
int num[1<<20];
const int MAXN=1e9+1;
// bool check()
// {
// int ans=0;
// for(int i=1;i<=n;i++)
// for(int j=1;j<=n;j++)
// ans+=abs(num[i]-num[j]);
// if(ans==0)
// {
// for(int i=1;i<=n;i++) cout<<num[i]<<" ";
// cout<<"\n\n";
// }
// }
// void dfs(int i)
// {
// if(i>n) {check(); return;}
// for(int i=a[i].l;i<=a[i].r;i++)
// {
// num[i]=i;
// dfs(i+1);
// }
// }
// unordered_map<int,bool> mp;
/*
int check(int mid)
{
for(int i=1;i<=n;i++)
{
num[i]=mid;
if(a[i].r<mid) num[i]=a[i].r;
if(a[i].l>mid) num[i]=a[i].l;
}
sort(num+1,num+1+n);
int nw=0,ans=0;
for(int i=1;i<=n;i++)
{
nw+=num[i];
ans+=i*num[i]-nw;
}
if(ans*2==20)
{
for(int i=1;i<=n;i++) cout<<num[i]<<" ";
cout<<"\n";
}
return ans*2;
}*/
// int sum[1<<20];
priority_queue<int,vector<int>,greater<int> > s;
int sum_l[1<<20],sum_r[1<<20];
int pre=0,sum=0,siz=0;
int check1(int i)// search for l
{
int ans=0;
while(s.size()&&s.top()<=a[i].l)
{
int x=s.top();
s.pop();
siz++;
sum+=x;
pre+=x*siz-sum;
}
ans=pre
+(siz*a[i].l-sum)*s.size()
+(sum_l[n]-sum_l[i])*i-(n-i)*(sum+s.size()*a[i].l)
+sum_r[i+1];
return ans*2;
}
// int check2(int i)// const val_r
// {
// }
signed main()
{
n=read();
for(int i=1;i<=n;i++)
{
int l=read(),r=read();
a[i]={l,r};
}
int ans=4e18+5;
sort(a+1,a+1+n,cmp1);
for(int i=1;i<=n;i++) sum_l[i]=sum_l[i-1]+a[i].l;
for(int i=n;i>=1;i--)
{
sum+=a[i].l;
sum_r[i]=sum_r[i+1]+sum-a[i].l*(n-i+1);
}
sum=pre=siz=0;
for(int i=1;i<=n;i++)
{
s.push(a[i].r);
while(i<n&&a[i+1].l==a[i].l)
{
i++;
s.push(a[i].r);
}
ans=min(ans,check1(i));
}
for(int i=1;i<=n;i++)
{
swap(a[i].l,a[i].r);
a[i].l=MAXN-a[i].l;
a[i].r=MAXN-a[i].r;
// write(a[i].l);
// putchar(' ');
// write(a[i].r);
// putchar('\n');
}
// cout<<"\n\n-----------------------\n\n\n";
sort(a+1,a+1+n,cmp1);
// for(int i=1;i<=n;i++)
// {
// // // swap(a[i].l,a[i].r);
// // // a[i].l=MAXN-a[i].l;
// // // a[i].r=MAXN-a[i].r;
// write(a[i].l);
// putchar(' ');
// write(a[i].r);
// putchar('\n');
// }
memset(sum_l,0,sizeof(sum_l));
sum=pre=siz=0;
memset(sum_r,0,sizeof(sum_r));
while(s.size()) s.pop();
for(int i=1;i<=n;i++) sum_l[i]=sum_l[i-1]+a[i].l;
for(int i=n;i>=1;i--)
{
sum+=a[i].l;
sum_r[i]=sum_r[i+1]+sum-a[i].l*(n-i+1);
}
sum=pre=siz=0;
for(int i=1;i<=n;i++)
{
s.push(a[i].r);
while(i<n&&a[i+1].l==a[i].l)
{
i++;
s.push(a[i].r);
}
// cout<<"a[i].l=";write(a[i].l);cout<<" check(i)=";write(check1(i));cout<<"\n";
ans=min(ans,check1(i));
}
write(ans);
return 0;
}
7.23
同余最短路。
板子题。
点击查看代码
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
int dis[1<<20];
bool vis[1<<20];
vector<int> E[1<<20],V[1<<20];
void add(int u,int v,int w)
{
E[u].push_back(v);
V[u].push_back(w);
}
void dij(int s)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<(1<<20);i++) dis[i]=LONG_LONG_MAX+1ull;
dis[0]=1;
// q.push(make_pair(0,0));
q.push(make_pair(0,0));
while(q.size())
{
int x=q.top().second;
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=0;i<E[x].size();i++)
{
int to=E[x][i];
int w=V[x][i];
if(vis[to]) continue;
if(dis[to]<dis[x]+w) continue;
dis[to]=dis[x]+w;
q.push(make_pair(dis[to],to));
}
}
}
int h,x,y,z;
signed main()
{
//mt19937_64 myrand(time(0));
cin>>h>>x>>y>>z;
if(x==1||y==1||z==1) { cout<<h; return 0; }
for(int i=0;i<x;i++)
{
add(i,(y+i)%x,y);
add(i,(z+i)%x,z);
}
dij(0);
int ans=0;
for(int i=0;i<x;i++)
{
if(h>=dis[i]) ans+=(h-dis[i])/x+1;
}
cout<<ans<<"\n";
return 0;
}
还是板子。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n;
int a[1<<20];
int dis[1<<20];
bool vis[1<<20];
vector<int> E[1<<20],V[1<<20];
void add(int u,int v,int w)
{
E[u].push_back(v);
V[u].push_back(w);
}
void dij()
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
dis[0]=0;
q.push(make_pair(0,0));
while(q.size())
{
int x=q.top().second;
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=0;i<E[x].size();i++)
{
int to=E[x][i];
int w=V[x][i];
if(vis[to]) continue;
if(dis[to]<dis[x]+w) continue;
dis[to]=dis[x]+w;
q.push(make_pair(dis[to],to));
}
}
}
int l,r;
signed main()
{
n=read(),l=read(),r=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
if(a[i]==0) n--,i--;
}
if(n==0) { cout<<0; return 0; }
sort(a+1,a+1+n);
for(int i=0;i<a[1];i++)
for(int j=2;j<=n;j++)
add(i,(i+a[j])%a[1],a[j]);
dij();
int ans=0;
for(int i=0;i<a[1];i++)
{
if(r<dis[i]) continue;
// cout<<dis[i]<<" ";
int num_r=(r-dis[i])/a[1]+1;
int num_l=0;
if(l-1-dis[i]>=0) num_l=(l-1-dis[i])/a[1]+1;
// if(num_l<0) num_l=0;
// cout<<"i="<<i<<" dis="<<dis[i]<<" num_r="<<num_r<<" num_l="<<num_l<<"\n";
ans+=num_r-num_l;
}
cout<<ans<<"\n";
//mt19937_64 myrand(time(0));
return 0;
}
7.24
杂题。
P9340 [JOIST 2023] 旅行 / Tourism
回滚莫队,需要用到虚树思想:【包含所有关键点的连通块最小大小】:虚树中边的数量等于按 dfs 序排序后两两相邻的点的距离之和。(第一个和最后一个也相邻)
点击查看代码
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+5;
const int M=1e5+5;
int n,m,q;
int c[M];
// int u[N],v[N];
int cnt,dfn[M];
int tot,st[19][N];
// int id[N];
int dep[M];
int logn[N];
int L[M],R[M];
// int cnt=0;
vector<int> E[M];
int id[M];
const int len=500;
struct Q{
int l,r,i;
}ask[M];
int ans[M];
bool cmp(Q x,Q y) { return id[x.l]==id[y.l]?x.r>y.r:x.l<y.l; }
int pre[100005],nxt[100005];
int sum=0;
int T[100005];
int num[100005];
int to[100005];
int head,tail;
void dfs(int p,int fa)
{
++tot;
++cnt;
dfn[p]=cnt;
dep[p]=dep[fa]+1;
to[cnt]=p;
st[0][tot]=dep[p];
L[p]=tot;
for(int to:E[p])
{
if(to==fa) continue;
dfs(to,p);
st[0][++tot]=dep[p];
}
R[p]=tot;
}
int lca(int l,int r)
{
int k=logn[r-l+1];
return min(st[k][l],st[k][r-(1<<k)+1]);
}
void del(int col)
{
int l=pre[col],mid=col,r=nxt[col];
if(l==-1) l=tail,head=r;
if(r==n+1) r=head,tail=l;
// if(col==8) cout<<"l="<<l<<" mid="<<mid<<" r="<<r<<"\n";
// cout<<"l="<<l<<" r="<<r<<" ";
// l=to[l];
// mid=col;
// r=to[r];
// cerr<<"l="<<l<<" mid="<<mid<<" r="<<r<<"\n";
sum-=dep[l]+dep[mid]-2*lca(min(L[l],L[mid]),max(R[l],R[mid]));
sum-=dep[mid]+dep[r]-2*lca(min(L[mid],L[r]),max(R[mid],R[r]));
sum+=dep[l]+dep[r]-2*lca(min(L[l],L[r]),max(R[l],R[r]));
if(nxt[col]<=n) pre[nxt[col]]=pre[col];
if(pre[col]>0) nxt[pre[col]]=nxt[col];
}
// int deep;
void baoli(int l,int r)
{
// cerr<<"l="<<l<<" r="<<r<<"\n";
if(l>r) return;
// deep++;
// cout<<"l="<<l<<" deep="<<deep<<"\n";
// int nw=c[l],ans=0;
num[c[l]]--;
if(!num[c[l]])
{
// if(c[l]==8) cout<<"knsd;na";
int col=c[l];
int lt=tail,lh=head;
int pr=0,nx=0;
if(nxt[col]<=n) pr=pre[nxt[col]];
if(pre[col]>0) nx=nxt[pre[col]];
// if(c[l]==8)
// {
// cout<<sum<<" ";
// }
del(c[l]);
// if(c[l]==8) cout<<sum<<" ";
// cout<<"l="<<l<<" c[l]="<<c[l]<<" sum="<<sum<<"\n";
baoli(l+1,r);
tail=lt;
head=lh;
if(nxt[col]<=n)pre[nxt[col]]=pr;
if(pre[col]>0) nxt[pre[col]]=nx;
}
else baoli(l+1,r);
num[c[l]]++;
}
void solve(int ql,int qr,int lid)
{
const int sl=max((lid-1)*len,1);
// cerr<<"ql="<<ql<<" qr="<<qr<<" qid="<<lid<<" sl="<<sl<<"\n";
sum=head=tail=0;
memset(num,0,sizeof(num));
memset(T,0,sizeof(T));
// memset(pre,-1,sizeof(pre));
// memset(nxt,0,sizeof(nxt));
for(int i=1;i<=n;i++)
{
pre[i]=-1;
nxt[i]=n+1;
}
// cout<<"sl="<<sl<<" sum="<<sum<<"\n";
for(int i=sl;i<=m;i++) num[c[i]]++;
for(int i=sl;i<=m;i++) T[dfn[c[i]]]=1;
int last=-1,first=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
if(T[i])
{
if(last>=0) pre[to[i]]=to[last];
else pre[to[i]]=-1;
first=min(first,i);
if(last>0) sum+=dep[to[last]]+dep[to[i]]-2*lca(min(L[to[last]],L[to[i]]),max(R[to[last]],R[to[i]]));
last=i;
}
}
tail=to[last];
sum+=dep[to[last]]+dep[to[first]]-2*lca(min(L[to[last]],L[to[first]]),max(R[to[last]],R[to[first]]));
last=n+1;
for(int i=n;i>=1;i--)
{
if(T[i])
{
if(last<=n) nxt[to[i]]=to[last];
else nxt[to[i]]=n+1;
last=i;
}
}
head=to[last];
int r=m;
// if(ql==3)for(int i=1;i<=n;i++) cerr<<"i="<<i<<" pre="<<pre[i]<<" nxt="<<nxt[i]<<"\n";
for(int i=ql;i<=qr;i++)
{
// cerr<<ql<<" "<<qr<<"\n";
while(r>ask[i].r)
{
num[c[r]]--;
if(num[c[r]]==0) del(c[r]);
r--;
}
int summ=sum;
// cout<<"r="<<r<<" l="<<sl<<"\n";
// cerr<<summ/2+1<<"\n";
// cerr<<"sum="<<sum/2+1<<"\n";
baoli(sl,ask[i].l-1);
// cout<<" sum="<<sum<<"\n";
ans[ask[i].i]=sum/2+1;
// cerr<<"sum="<<sum/2+1<<"\n";
// cerr<<sum/2+1<<"\n";
sum=summ;
}
// cerr<<"\n\n";
}
bool cmp1(int l,int r){ return dfn[l]<dfn[r]; }
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
// freopen("P9340_56.in","r",stdin);
// freopen("baoli.out","w",stdout);
for(int i=1;i<=100000;i++) id[i]=i/len+1;
for(int i=2;i<(N);i++) logn[i]=logn[i>>1]+1;
cin>>n>>m>>q;
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
E[u].push_back(v);
E[v].push_back(u);
}
for(int i=1;i<=m;i++) cin>>c[i];
dfs(1,0);
// for(int i=1;i<=n;i++)
// {
// cout<<"i="<<i<<" dfn="<<dfn[i]<<"\n";
// }
for(int k=1;k<=logn[tot];k++)
for(int i=1;i<=tot;i++)
st[k][i]=min(st[k-1][i],st[k-1][i+(1<<(k-1))]);
for(int i=1;i<=q;i++)
{
int l,r;
cin>>l>>r;
ask[i]={l,r,i};
}
sort(ask+1,ask+1+q,cmp);
// for(int i=1;i<=n;i++) cout<<L[i]<<" "<<R[i]<<"\n";
// cout<<"\n\n";
for(int i=1;i<=q;i++)
{
int l=ask[i].l,r=ask[i].r;
if(id[l]==id[r])
{
int a[505]={},len=r-l+1,sum=0;
for(int i=l;i<=r;i++) a[i-l+1]=c[i];
sort(a+1,a+1+len,cmp1);
a[len+1]=a[1];
for(int i=1;i<=len;i++)
sum+=dep[a[i]]+dep[a[i+1]]-2*lca(min(L[a[i]],L[a[i+1]]),max(R[a[i]],R[a[i+1]]));
ans[ask[i].i]=sum/2+1;
continue;
}
int nw=i;
while(id[ask[i+1].l]==id[l]) i++;
solve(nw,i,id[l]);
}
for(int i=1;i<=q;i++) cout<<ans[i]<<"\n";
return 0;
}
/*
10 9 10
1 2
1 3
3 4
1 5
3 6
5 7
4 8
5 9
5 10
2 2 4 2 2 5 6 9 3
1 9
1 3
8 9
5 7
2 5
7 8
1 4
9 9
3 3
2 6
7
4
4
5
4
5
4
1
1
5
*/
7.26
淀粉质和 CDQ 分治。
淀粉质比较版的题。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=4e4+5;
int n;
vector<int> E[N],V[N];
void add(int u,int v,int w)
{
E[u].push_back(v);
V[u].push_back(w);
}
int dis[N];
bool vis[N];
int siz[N];
void dfs(int p,int fa)
{
siz[p]=1;
// cerr<<p<<"\n";
for(int i=0;i<E[p].size();i++)
{
int to=E[p][i];
int w=V[p][i];
if(to==fa) continue;
if(vis[to]) continue;
dis[to]=w%3;
dfs(to,p);
siz[p]+=siz[to];
}
}
pair<int,int> dfs2(int p,int fa,const int root_siz)
{
int maxn=0;
pair<int,int> nw=make_pair(n+1,p);
// siz[p]=1;
for(int to:E[p])
if(to!=fa&&vis[to]==0) nw=min(nw,dfs2(to,p,root_siz)),maxn=max(maxn,siz[to]);
// cerr<<"p="<<p<<" fa="<<fa<<" root_siz="<<root_siz<<" s_maxn="<<maxn<<"\n";
return min(nw,make_pair(max(maxn,root_siz-siz[p]),p));
}
int t[3];
int t_nw[3];
int ans[3];
void dfs3(int root,int p,int fa,int sum)
{
// if(p!=root)
t_nw[sum]++;
for(int to:E[p])
if(to!=fa&&vis[to]==0) dfs3(root,to,p,(sum+dis[to])%3);
}
void solve(int root)
{
vis[root]=1;
// cerr<<"root="<<root<<"\n";
dfs(root,0);
int maxn_siz=siz[root];
for(int to:E[root])
{
if(vis[to]) continue;
// cerr<<"root="<<root<<" to="<<to<<"\n";
// cerr<<"to="<<to<<" root="<<root<<"\n";
// dfs(to,root);
// cerr<<"to="<<to<<" root="<<root<<"\n";
if(siz[to]>1)
{
int too=dfs2(to,root,maxn_siz).second;
// cerr<<"root="<<root<<" nxt_root="<<too<<"\n";
solve(too);
}
}
// cerr<<"\nroot="<<root<<"\n";
dfs(root,0);
memset(t,0,sizeof(t));
t[0]=1;
for(int to:E[root])
{
if(vis[to]) continue;
memset(t_nw,0,sizeof(t_nw));
// cout<<"root="<<root<<" p="<<to<<" fa="<<root<<"\n";
dfs3(root,to,root,dis[to]);
// cerr<<"to="<<to<<"\n";
// for(int i=0;i<3;i++) cerr<<"t_nw["<<i<<"]="<<t_nw[i]<<" ";
// cerr<<"\n";
// for(int i=0;i<3;i++) cerr<<"t["<<i<<"]="<<t[i]<<" ";
// cerr<<"\n";
// ans[0]+=t_nw[0];
// ans[1]+=t_nw[1];
// ans[2]+=t_nw[2];
ans[0]+=(t_nw[1]*t[2]+t_nw[2]*t[1]+t_nw[0]*t[0])*2;
ans[1]+=(t_nw[0]*t[1]+t_nw[1]*t[0]+t_nw[2]*t[2])*2;
ans[2]+=(t_nw[0]*t[2]+t_nw[1]*t[1]+t_nw[2]*t[0])*2;
t[0]+=t_nw[0];
t[1]+=t_nw[1];
t[2]+=t_nw[2];
}
// cout<<"root="<<root<<"\n";
// cerr<<"\n";
// for(int i=0;i<3;i++) cerr<<"ans["<<i<<"]="<<ans[i]<<" ";
// cerr<<"\n";
vis[root]=0;
}
signed main()
{
n=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read(),w=read()%3;
add(u,v,w);
add(v,u,w);
}
// cerr<<"nbdsdnojusa\n";
dfs(1,0);
// cerr<<"nbdsdnojusa\n";
ans[0]=n;
// cout<<ans[0]<<" ";
solve(dfs2(1,0,siz[1]).second);
// cerr<<"nbdsdnojusa\n";
// cout<<ans[0]<<" ";
int a=ans[0];
int b=n*n,chu=__gcd(a,b);
a/=chu;
b/=chu;
cout<<a<<"/"<<b<<"\n";
return 0;
}
也是板子。
点击查看代码
#include<bits/stdc++.h>
// #define int long long
using namespace std;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=2e5+5;
int n,k;
vector<int> E[N],V[N];
void add(int u,int v,int w)
{
E[u].push_back(v);
V[u].push_back(w);
}
int dis[N];
bool vis[N];
int siz[N];
void dfs(int p,int fa)
{
siz[p]=1;
for(int i=0;i<E[p].size();i++)
{
int to=E[p][i];
int w=V[p][i];
if(to==fa) continue;
if(vis[to]) continue;
dis[to]=w;
dfs(to,p);
siz[p]+=siz[to];
}
}
pair<int,int> dfs2(int p,int fa,const int root_siz)
{
int maxn=0;
pair<int,int> nw=make_pair(n+1,p);
for(int to:E[p])
if(to!=fa&&vis[to]==0) nw=min(nw,dfs2(to,p,root_siz)),maxn=max(maxn,siz[to]);
return min(nw,make_pair(max(maxn,root_siz-siz[p]),p));
}
// int t[3];
// int t_nw[3];
// int ans[3];
int ans=0x3f3f3f3f;
vector<int> v;
vector<pair<int,int> > v2;
int t[1<<20];
void dfs3(int root,int p,int fa,int sum,int cnt)
{
if(sum>k) return;
v2.push_back(make_pair(sum,cnt));
for(int to:E[p])
if(to!=fa&&vis[to]==0) dfs3(root,to,p,(sum+dis[to]),cnt+1);
}
void solve(int root)
{
vis[root]=1;
dfs(root,0);
int maxn_siz=siz[root];
for(int to:E[root])
{
if(vis[to]) continue;
if(siz[to]>1)
{
int too=dfs2(to,root,maxn_siz).second;
solve(too);
}
}
v.clear();
v2.clear();
t[0]=0;
dfs(root,0);
// cout<<"\n\n---------------------------------------------\n\n";
for(int to:E[root])
{
if(vis[to]) continue;
dfs3(root,to,root,dis[to],1);
for(auto i:v2) ans=min(ans,i.second+t[k-i.first]);//cout<<"sum="<<i.first<<" ";
// cout<<"\n";
// if(v.size()<v2.size()) swap(v,v2);
for(auto i:v2)
t[i.first]=min(t[i.first],i.second),v.push_back(i.first);
v2.clear();
}
for(int i:v) t[i]=0x3f3f3f3f;
vis[root]=0;
}
signed main()
{
memset(t,0x3f,sizeof(t));
n=read();
k=read();
for(int i=1;i<n;i++)
{
int u=read()+1,v=read()+1,w=read();
add(u,v,w);
add(v,u,w);
}
dfs(1,0);
solve(dfs2(1,0,siz[1]).second);
if(ans==0x3f3f3f3f) ans=-1;
cout<<ans;
return 0;
}
7.27:
APJifengc 来讲课了!!
manacher 和 SA。
manacher 板子。
点击查看代码
#include<stdio.h>
#include<cstring>
// #define int long long
// using namespace std;
//
const int N=2.2e7+100;
char aaa[N],a[N];
int cnt;
signed p[N];
signed ans;
inline int min(int x,int y) { return x<y?x:y; }
signed main()
{
scanf("%s",aaa);
a[cnt]='$';
a[++cnt]='|';
int len=strlen(aaa);
for(int i=1;i<len;i++)
{
a[++cnt]=aaa[i-1];
a[++cnt]='|';
}
a[++cnt]=aaa[len-1];
a[++cnt]='|';
a[++cnt]='*';
for(int i=1,r=0,mid=0;i<=cnt;i++)
{
if(i<=r) p[i]=min(p[2*mid-i],r-i+1);
while(a[i+p[i]]==a[i-p[i]]) p[i]++;
if(i+p[i]>r) { r=i+p[i]-1; mid=i; }
if(p[i]>ans) ans=p[i];
}
printf("%d",ans-1);
//mt19937_64 myrand(time(0));
return 0;
}
也是板子。稍微改一改就过了。
点击查看代码
#include<stdio.h>
#include<cstring>
// #include<bits/stdc++.h>
// using namespace std;
#define int long long
//
const int N=1e6+100;
char aaa[N],a[N];
int cnt;
int p[N];
int ans;
bool f[N];
inline int min(int x,int y) { return x<y?x:y; }
inline int max(int x,int y) { return x>y?x:y; }
signed main()
{
int len=0;
scanf("%d%s",&len,aaa);
a[cnt]='$';
a[++cnt]='|';
for(int i=1;i<len;i++)
{
cnt++;
f[cnt]=1;
a[cnt]=aaa[i-1];
a[++cnt]='|';
// cerr<<cnt<<"\n";
}
++cnt;
a[cnt]=aaa[len-1];
f[cnt]=1;
a[++cnt]='|';
a[++cnt]='*';
// printf("%s\n",a);
// for(int i=1;i<=cnt;i++) cout<<f[i];
// cout<<'\n';
// return 0;
// f[0]=f[cnt]=1;
for(int i=1,r=0,mid=0;i<=cnt;i++)
{
if(i<=r) p[i]=min(p[2*mid-i],r-i+1);
p[i]=max(p[i],1ll);
// cerr<<"i="<<i<<" mid="<<mid<<" r="<<r<<" p[i]="<<p[i]<<" f[i+p[i]]="<<f[i+p[i]]<<" a[i+p[i]]="<<a[i+p[i]]<<" f[i-p[i]]="<<f[i-p[i]]<<" a[i-p[i]]="<<a[i-p[i]]<<"\n";
while((f[i+p[i]]==0&&f[i-p[i]]==0&&a[i+p[i]]==a[i-p[i]])||(f[i-p[i]]==1&&f[i+p[i]]==1&&a[i+p[i]]!=a[i-p[i]]))
{
p[i]++;
// if(i==10) cout<<"i="<<i<<" p[i]="<<p[i]<<" i+p[i]="<<i+p[i]<<" i-p[i]="<<i-p[i]<<" a[i+p[i]]="<<a[i+p[i]]<<" a[i-p[i]]="<<a[i-p[i]]<<"\n";
}
if(i+p[i]>r&&!f[i]) { r=i+p[i]-1; mid=i; }
if(f[i]==0) ans+=p[i]>>1;//,cout<<"i="<<i<<" p[i]="<<p[i]<<"\n";
}
printf("%lld",ans);
return 0;
}
没啥可说的。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1<<20;
char s[N];
int n,m;
int y[N],x[N],c[N],sa[N],rk[N],height[N],wt[30];
void SA()
{
for(int i=1;i<=n;i++) ++c[x[i]=s[i]];
for(int i=2;i<=m;i++) c[i]+=c[i-1];
for(int i=n;i>=1;i--) sa[c[x[i]]--]=i;
for(int k=1;k<n;k<<=1)
{
int num=0;
for(int i=n-k+1;i<=n;i++) y[++num]=i;
for(int i=1;i<=n;i++) if(sa[i]>k) y[++num]=sa[i]-k;
for(int i=1;i<=m;i++) c[i]=0;
for(int i=1;i<=n;i++) ++c[x[i]];
for(int i=2;i<=m;i++) c[i]+=c[i-1];
for(int i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i],y[i]=0;
swap(x,y);x[sa[1]]=1;num=1;
for(int i=2;i<=n;i++)
x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
if(num==n) break;
m=num;
}
for(int i=1;i<=n;i++) printf("%lld ",sa[i]);
}
void get_height()
{
int k=0;
for(int i=1;i<=n;i++) rk[sa[i]]=i;
for(int i=1;i<=n;i++)
{
if(rk[i]==0) continue;
if(k) k--;
int j=sa[rk[i]-1];
while(j+k<=n&&i+k<=n&&s[i+k]==s[j+k]) k++;
height[rk[i]]=i;
}
putchar('\n');
for(int i=1;i<=n;i++)
printf("%lld ",height[i]);
}
signed main()
{
scanf("%s",s+1);
n=strlen(s+1);
m=122;
SA();
return 0;
}
没啥好说的。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=1<<20;
char s[N];
int ans;
struct SAM{
signed len[N<<1],link[N<<1];
signed ch[N<<1][26];
signed f[N<<1];
vector<signed> v[N<<1];
signed last=0,siz=0;
inline void init()
{
for(int i=0;i<(N<<1);i++) v[i].clear();
memset(len,0,sizeof(len));
memset(link,0,sizeof(link));
memset(ch,0,sizeof(ch));
link[0]=-1;
siz=last=0;
}
inline void extend(char *s)
{
int n=strlen(s);
for(int i=0;i<n;i++)
{
int c=s[i]-'a',p=last,cur=++siz;
len[cur]=len[p]+1;
f[cur]=1;
while(p!=-1&&!ch[p][c])
{
ch[p][c]=cur;
p=link[p];
}
if(p==-1) link[cur]=0;
else
{
int q=ch[p][c];
if(len[q]==len[p]+1) link[cur]=q;
else
{
int copy=++siz;
len[copy]=len[p]+1;
link[copy]=link[q];
for(int i=0;i<26;i++) ch[copy][i]=ch[q][i];
while(p!=-1&&ch[p][c]==q)
{
ch[p][c]=copy;
p=link[p];
}
link[q]=link[cur]=copy;
}
}
last=cur;
}
for(int i=1;i<=siz;i++) v[link[i]].push_back(i);
}
inline int dfs(int x)
{
for(int i=0;i<v[x].size();i++)
{
int y=v[x][i];
dfs(y);
f[x]+=f[y];
}
if(f[x]>1) ans=max(ans,1ll*f[x]*len[x]);
return f[x];
}
}sam;
signed main()
{
scanf("%s",s);
sam.init();
sam.extend(s);
sam.dfs(0);
write(ans),putchar('\n');
//mt19937_64 myrand(time(0));
return 0;
}
7.28
APJifengc 来讲回文自动机和后缀自动机了!!
基础 manacher 练习题。
点击查看代码
#include<stdio.h>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
#define int long long
const int N=(1<<21)+100;
char aaa[N],a[N];
int cnt;
signed p[N];
const int mod=19930726;
inline int min(int x,int y) { return x<y?x:y; }
int ans[N];
int n,k;
int ksm(int a,int b)
{
int ans=1;
while(b)
{
if(b&1) ans*=a,ans%=mod;
b>>=1;
a*=a;
a%=mod;
}
return ans;
}
signed main()
{
scanf("%lld%lld%s",&n,&k,aaa);
a[cnt]='$';
a[++cnt]='|';
int len=strlen(aaa);
for(int i=1;i<=len;i++)
{
a[++cnt]=aaa[i-1];
a[++cnt]='|';
}
a[++cnt]='*';
for(int i=1,r=0,mid=0;i<=cnt;i++)
{
if(i<=r) p[i]=min(p[2*mid-i],r-i+1);
while(a[i+p[i]]==a[i-p[i]]) p[i]++;
if(i+p[i]>r) { r=i+p[i]-1; mid=i; }
ans[p[i]-1]++;
}
int nw=1;
for(int i=cnt;i>0;i--)
{
if(i%2==0)
{
ans[i-2]+=ans[i];
ans[1]+=ans[i]*2;
continue;
}
if(ans[i])
{
// cout<<"i="<<i<<" ans[i]="<<ans[i]<<" k="<<k<<"\n";
if(ans[i]>=k)
{
nw*=ksm(i,k);
nw%=mod;
k=0;
break;
}
k-=ans[i];
// if(i-2>=0) ans[i-2]+=ans[i];
if(i-2>=0)ans[i-2]+=ans[i];
ans[1]+=ans[i]*2;
nw*=ksm(i,ans[i]);
nw%=mod;
}
}
if(!k) printf("%lld",nw);
else printf("-1");
//mt19937_64 myrand(time(0));
return 0;
}
/*
10 10
abbaaabbbb
945
*/
manacher 巧思一下。
和题解区一篇写的很像。
点击查看代码
#include<stdio.h>
#include<cstring>
#include<bits/stdc++.h>
// #define int long long
using namespace std;
//
/*
16
ggabaabaabaaball
*/
const int N=1e6+100;
char aaa[N],a[N];
int cnt;
signed p[N];
signed ans;
inline int min(int x,int y) { return x<y?x:y; }
bool f[N];
// set<int> s[N];
// priority_queue<int,vector<int>,greater<int> >q;
struct T{
int lp,rp,maxn;
}t[1<<20<<2];
int tot;
const int MINN=0;
void add(int l,int r,int x,int val,int &p)
{
if(!p) p=++tot;
if(l==r)
{
t[p].maxn=val;
return;
}
int mid=(l+r)>>1;
if(x<=mid) add(l,mid,x,val,t[p].lp);
else add(mid+1,r,x,val,t[p].rp);
t[p].maxn=max(t[t[p].lp].maxn,t[t[p].rp].maxn);
}
int query2(int l,int r,int sl,int sr,int p)
{
if(sl>sr) return MINN;
if(!p) return MINN;
if(sl<=l&&r<=sr) return t[p].maxn;
int mid=(l+r)>>1,ans=0;
if(sl<=mid) ans=max(ans,query2(l,mid,sl,sr,t[p].lp));
if(sr>mid) ans=max(ans,query2(mid+1,r,sl,sr,t[p].rp));
return ans;
}
int query(int l,int r,int sl,int sr,int qr,int p)
{
// cerr<<"l="<<l<<" r="<<r<<" sl="<<sl<<" sr="<<sr<<"\n";
if(sl>sr) return MINN;
if(l==r)
{
// cerr<<"l="<<l<<" r="<<r<<" t[p].maxn"<<t[p].maxn<<" qr="<<qr<<" -> "<<(t[p].maxn>=qr?l:0)<<"\n";
return t[p].maxn>=qr?l:0;
}
int mid=(l+r)>>1,ans=0;
if(sl<=mid)
{
if(query2(l,mid,sl,mid,t[p].lp)>=qr) return query(l,mid,sl,min(mid,sr),qr,t[p].lp);
return query(mid+1,r,max(sl,mid+1),sr,qr,t[p].rp);
}
return query(mid+1,r,max(sl,mid+1),sr,qr,t[p].rp);
}
signed main()
{
int nnn;
scanf("%d%s",&nnn,aaa);
// printf("%d\n",nnn);
a[cnt]='$';
a[++cnt]='|';
f[cnt]=1;
int len=strlen(aaa);
// printf("%d\n",len);
for(int i=1;i<=len;i++)
{
a[++cnt]=aaa[i-1];
a[++cnt]='|';
f[cnt]=1;
}
a[++cnt]='*';
int root=0;
// printf("%s\n",a);
for(int i=1,r=0,mid=0,aa=0;i<=cnt;i++)
{
// cerr<<"\n----------------------------\ni="<<i<<"\n";
if(i<=r) p[i]=min(p[2*mid-i],r-i+1);
while(a[i+p[i]]==a[i-p[i]]) p[i]++;
if(i+p[i]>r) { r=i+p[i]-1; mid=i; }
int l=i-(p[i]-1)/2;
if(a[i]=='|')
{
// cerr<<"p[i]="<<p[i]<<" ql="<<i-p[i]+1<<" mid="<<i<<" qr="<<i+p[i]-1<<"\n";
// cerr<<"sl="<<l<<" sr="<<i-1<<" \n";
int op=query(1,cnt,l,i-1,i-1,root);
if(op) ans=max(ans,(i-op));
// cerr<<"maxn -> "<<ans<<"\n";
add(1,cnt,i,i+p[i]-1,root);
// cerr<<"i="<<i<<" op="<<op<<" add="<<i+p[i]-1<<"\n";
}
// else cerr<<"cnt="<<++aa<<" i="<<i<<" "<<a[i]<<"\n";
}
// for(int i=1;i<=len;i++) h[i]=h[i-1]*prime+aaa[i-1];
printf("%d",ans*2);
//mt19937_64 myrand(time(0));
return 0;
}
7.29
大困难题,写了 6 个 dfs 终于过了!!!
点击查看代码
#include<bits/stdc++.h>
// #define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
/*
8 1
1 10 100 1000 10000 100000 1000000 10000000
1 2
1 3
2 4
2 5
3 6
3 7
3 8
0 3 1
*/
const int N=1e5+5;
int n,m;
vector<int> E[N],G[N];
bool vis[N];
void addddd(int u,int v) { G[u].push_back(v);}
int siz[N];
bool can[N];
const int MAXN=N,MINN=0;
int st[19][N<<2];
int L[N],R[N];
int tot;
int logn[N<<2];
int dep[N];
int val[N];
int f[N];
void dfs0(int p,int fa)
{
dep[p]=dep[fa]+1;
st[0][++tot]=dep[p];
L[p]=tot;
for(int to:G[p])
if(to!=fa) dfs0(to,p),st[0][++tot]=dep[p];
R[p]=tot;
}
void dfs1(int p,int fa)
{
siz[p]=1;
for(int i=0;i<G[p].size();i++)
{
int to=G[p][i];
if(to==fa||vis[to]) continue;
dfs1(to,p);
siz[p]+=siz[to];
}
}
inline pair<int,int> minn(pair<int,int> x,pair<int,int> y)
{
if(x.first<y.first) return x;
else return y;
}
inline pair<int,int> dfs2(int p,int fa,const int maxn_siz)
{
pair<int,int> ans1=make_pair(MAXN,0);
int maxn=0;
for(int i=0;i<G[p].size();i++)
{
int to=G[p][i];
if(to==fa||vis[to]) continue;
ans1=minn(ans1,dfs2(to,p,maxn_siz));
maxn=max(maxn,siz[to]);
}
return minn(ans1,make_pair(max(maxn,maxn_siz-siz[p]),p));
}
// vector<int> v;
void dfs3(int root)
{
vis[root]=1;
siz[root]=0;
for(int i=0;i<G[root].size();i++)
{
int to=G[root][i];
if(vis[to]) continue;
dfs1(to,root);
int to_root=dfs2(to,root,siz[to]).second;
if(!(to_root<1||to_root>n))
{
dfs3(to_root);
E[root].push_back(to_root);
E[to_root].push_back(root);
}
}
}
int find(int l,int r)
{
int x=min(L[l],L[r]);
int y=max(R[l],R[r]);
int k=logn[y-x+1];
// cout<<"dep[x]="<<dep[x]<<" dep[y]="<<dep[]
return dep[l]+dep[r]-2*min(st[k][x],st[k][y-(1<<k)+1]);
}
struct Tree{
struct T{
int lp,rp;
int val;
}t[N*17*2];
int root[N],cnt=0;
void add(int l,int r,int x,int val,int &p)
{
if(!p) p=++cnt;
if(l==r) { t[p].val+=val; return; }
int mid=(l+r)>>1;
if(x<=mid) add(l,mid,x,val,t[p].lp);
if(x>mid) add(mid+1,r,x,val,t[p].rp);
t[p].val=t[t[p].lp].val+t[t[p].rp].val;
}
void add(int x,int val,int rot)
{
add(MINN,MAXN,x,val,root[rot]);
}
int query(int l,int r,int sl,int sr,int p)
{
if(sl<=l&&r<=sr) return t[p].val;
int mid=(l+r)>>1,ans=0;
if(sl<=mid) ans=query(l,mid,sl,sr,t[p].lp);
if(sr>mid) ans+=query(mid+1,r,sl,sr,t[p].rp);
return ans;
}
int query(int dis,int rt)
{
return query(MINN,MAXN,MINN,dis,root[rt]);
}
}sont,fat;
void init()
{
for(int i=2;i<(N<<2);i++) logn[i]=logn[i>>1]+1;
for(int k=1;k<=logn[tot];k++)
for(int i=1;i<=tot;i++)
st[k][i]=min(st[k-1][i],st[k-1][i+(1<<(k-1))]);
}
int query(int l,int r)
{
if(l>r) swap(l,r);
int k=logn[r-l+1];
return min(st[k][l],st[k][r-(1<<k)+1]);
}
// void merge()
// {
// if(v2.size()>v.size()) swap(v2,v);
// for(int i:v2) v.push_back(i);
// v2.clear();
// }
vector<int> v;
void dfs5(int p,int fa)
{
v.push_back(p);
for(int to:G[p])
if(vis[to]==0&&to!=fa) dfs5(to,p);
}
void dfs4(int p,int fa)
{
// cerr<<fa<<" "<<p<<"\n";
f[p]=fa;
vis[p]=1;
for(int to:E[p])
if(to!=fa) dfs4(to,p);
v.push_back(p);
for(int to:G[p])
if(!vis[to]) dfs5(to,p);
for(int x:v)
{
sont.add(find(x,p),val[x],p);
fat.add(find(x,fa),val[x],p);
}
v.clear();
vis[p]=0;
}
signed main()
{
n=read();
m=read();
for(int i=1;i<=n;i++) val[i]=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read();
addddd(u,v);
addddd(v,u);
}
dfs0(1,0);
init();
dfs1(1,0);
int root=dfs2(1,0,n).second;
dfs3(root);
dfs4(root,0);
int lastans=0;
while(m--)
{
int op=read(),x=read()^lastans,y=read()^lastans;
if(op==0)
{
int nw=x;
lastans=sont.query(y,x);
// cout<<"lastans="<<lastans<<"\n";
for(int i=x;f[i];i=f[i])
{
int dis=find(x,f[i]);
// cout<<"dis="<<dis<<"\n";
if(y>=dis)
lastans+=sont.query(y-dis,f[i])-fat.query(y-dis,i);
}
cout<<lastans<<"\n";
}
if(op==1)
{
int nw=x;
while(x)
{
// val[x]*=-1;
sont.add(find(nw,x),y-val[nw],x);
if(f[x]) fat.add(find(nw,f[x]),y-val[nw],x);
x=f[x];
}
val[nw]=y;
}
}
return 0;
}
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
int ans=0;
// bool vis[105];
int siz;
int n,m,k,q;
int xc[105][105];//xiao qu coloe
struct MAP{
int col,b;
}mp[105][105];
int col[105];
int num[10][5],cnt[10];
struct Node{ int op,x,y; };
queue<Node> special;
int shot[105][105];//op==6
bool zhongju=1;
const int fx[4]={0,0,1,-1};
const int fy[4]={1,-1,0,0};
bool vis[105][105];
// ---------------------------------- check ---------------------------------------
bool check(int x,int y)
{
if(mp[x][y].col==0) return 0;
for(int l=x-2;l<=x;l++)
{
int r=l+2;
if(l<1||r>n) continue;
if(mp[l][y].col==mp[l+1][y].col&&mp[l+1][y].col==mp[r][y].col) return 1;
}
for(int l=y-2;l<=y;l++)
{
int r=l+2;
if(l<1||r>m) continue;
if(mp[x][l].col==mp[x][l+1].col&&mp[x][l+1].col==mp[x][r].col) return 1;
}
return 0;
}
//---------------------------------- end ------------------------------------------
//---------------------------------- bfs ------------------------------------------
void F1(int x,int y,int nw_c)
{
int to_x=x,to_y=y;
for(to_x=x-1;to_x>=1;to_x--)
{
if(mp[to_x][to_y].col!=nw_c) break;
if(!vis[to_x][to_y])
{
if(mp[to_x][to_y].b)
{
special.push({mp[to_x][to_y].b,to_x,to_y});
if(mp[to_x][to_y].b==6) shot[to_x][to_y]=mp[to_x][to_y].col;
}
siz+=nw_c;
xc[to_x][to_y]=mp[to_x][to_y].col;
// mp[to_x][to_y]={0,0};
}
vis[to_x][to_y]=1;
}
to_x=x,to_y=y;
for(to_x=x+1;to_x<=n;to_x++)
{
if(mp[to_x][to_y].col!=nw_c) break;
if(!vis[to_x][to_y])
{
if(mp[to_x][to_y].b)
{
special.push({mp[to_x][to_y].b,to_x,to_y});
if(mp[to_x][to_y].b==6) shot[to_x][to_y]=mp[to_x][to_y].col;
}
siz+=nw_c;
xc[to_x][to_y]=mp[to_x][to_y].col;
// mp[to_x][to_y]={0,0};
}
vis[to_x][to_y]=1;
}
}
void F2(int x,int y,int nw_c)
{
int to_x=x,to_y=y;
for(to_y=y-1;to_y>=1;to_y--)
{
if(mp[to_x][to_y].col!=nw_c) break;
if(!vis[to_x][to_y])
{
if(mp[to_x][to_y].b)
{
special.push({mp[to_x][to_y].b,to_x,to_y});
if(mp[to_x][to_y].b==6) shot[to_x][to_y]=mp[to_x][to_y].col;
}
siz+=nw_c;
xc[to_x][to_y]=mp[to_x][to_y].col;
// mp[to_x][to_y]={0,0};
}
vis[to_x][to_y]=1;
}
to_x=x,to_y=y;
for(to_y=y+1;to_y<=m;to_y++)
{
if(mp[to_x][to_y].col!=nw_c) break;
if(!vis[to_x][to_y])
{
if(mp[to_x][to_y].b)
{
special.push({mp[to_x][to_y].b,to_x,to_y});
if(mp[to_x][to_y].b==6) shot[to_x][to_y]=mp[to_x][to_y].col;
}
siz+=nw_c;
xc[to_x][to_y]=mp[to_x][to_y].col;
// mp[to_x][to_y]={0,0};
}
vis[to_x][to_y]=1;
}
}
void bfs(int x,int y)
{
int nw_c=mp[x][y].col;
if(!vis[x][y])siz+=nw_c,vis[x][y]=1;
xc[x][y]=nw_c;
bool f1=0,f2=0;
for(int l=x-2;l<=x;l++)
{
int r=l+2;
if(l<1||r>n) continue;
if(mp[l][y].col==mp[l+1][y].col&&mp[l+1][y].col==mp[r][y].col) f1=1;
}
for(int l=y-2;l<=y;l++)
{
int r=l+2;
if(l<1||r>m) continue;
if(mp[x][l].col==mp[x][l+1].col&&mp[x][l+1].col==mp[x][r].col) f2=1;
}
if(mp[x][y].b) special.push({mp[x][y].b,x,y});
if(mp[x][y].b==6) shot[x][y]=mp[x][y].col;
mp[x][y]={0,0};
if(f1) F1(x,y,nw_c);
if(f2) F2(x,y,nw_c);
}
int __bfs(int sx,int sy)
{
queue<pair<int,int>> q;
q.push(make_pair(sx,sy));
int tot=1;
int col=xc[sx][sy];
xc[sx][sy]=0;
while(q.size())
{
int x=q.front().first,y=q.front().second;
q.pop();
for(int i=0;i<4;i++)
{
int to_x=x+fx[i];
int to_y=y+fy[i];
if(xc[to_x][to_y]==col)
{
tot++;
xc[to_x][to_y]=0;
q.push(make_pair(to_x,to_y));
}
}
}
return 50*(tot-3)*(tot-3);
}
int __solve()
{
// for(int i=1;i<=n;cout<<"\n",i++)
// for(int j=1;j<=m;j++)
// cout<<xc[i][j]<<" ";
int nw=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(xc[i][j]) nw+=__bfs(i,j);
// cout<<"\n\n";
return nw;
}
//---------------------------------- end ------------------------------------------
// ------------------------------------ clear_special ----------------------------------------
//hang
void w1(int x,int y)
{
for(int i=1;i<=m;i++)
{
if(mp[x][i].col==0) continue;
// if(!vis[mp[x][i].col]) vis[mp[x][i].col]=1,siz+=mp[x][i].col;
siz+=mp[x][i].col;
if(mp[x][i].b) special.push({mp[x][i].b,x,i});
if(mp[x][i].b==6) shot[x][i]=mp[x][i].col;
mp[x][i]={0,0};
}
}
//lie
void w2(int x,int y)
{
for(int i=1;i<=n;i++)
{
if(mp[i][y].col==0) continue;
// if(!vis[mp[i][y].col]) vis[mp[i][y].col]=1,siz+=mp[i][y].col;
siz+=mp[i][y].col;
if(mp[i][y].b) special.push({mp[i][y].b,i,y});
if(mp[i][y].b==6) shot[i][y]=mp[i][y].col;
mp[i][y]={0,0};
}
}
void w4(int x,int y,int dt)
{
if(dt==3) dt=1;
else dt=2;
for(int i=x-dt;i<=x+dt;i++)
for(int j=y-dt;j<=y+dt;j++)
{
// cout<<i<<" "<<j<<"\n";
if(mp[i][j].col==0) continue;
// if(!vis[mp[i][j].col]) vis[mp[i][j].col]=1,siz+=mp[i][j].col;
siz+=mp[i][j].col;
if(mp[i][j].b) special.push({mp[i][j].b,i,j});
if(mp[i][j].b==6) shot[i][j]=mp[i][j].col;
mp[i][j]={0,0};
}
}
void w6(int x,int y)
{
int col=shot[x][y];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(mp[i][j].col==0) continue;
if(mp[i][j].col!=col) continue;
if(mp[i][j].b) special.push({mp[i][j].b,i,j});
if(mp[i][j].b==6) shot[i][j]=mp[i][j].col;
siz+=mp[i][j].col;
mp[i][j]={0,0};
}
}
void clear_special()
{
while(special.size())
{
int op=special.front().op,x=special.front().x,y=special.front().y;
special.pop();
if(op==1) w1(x,y);
if(op==2) w2(x,y);
if(op==3) w1(x,y),w2(x,y);
if(op==4) w4(x,y,3);
if(op==5) w4(x,y,5);
if(op==6) w6(x,y);
}
}
//-------------------------------------end ----------------------------------------------
//----------------------------------- check_map---------------------------------------
bool check_map()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(check(i,j)) return 1;
return 0;
}
//------------------------------------fall-----------------------------------------------
void fall()
{
vector<MAP> v;
for(int j=1;j<=m;j++)
{
v.clear();
for(int i=n;i>=1;i--)
{
if(mp[i][j].col) v.push_back(mp[i][j]);
}
while(v.size()<n) v.push_back({0,0});
for(int i=n,k=0;i>=1;i--,k++) mp[i][j]=v[k];
}
// cout<<"fall():\n";
// for(int i=1;i<=n;i++,cout<<"\n")
// for(int j=1;j<=m;j++)
// cout<<mp[i][j].col<<" ";
// cout<<"\n\n";
// for(int j=1;j<=m;j++)
// {
// int i=n;
// int last=n;
// while(i>=1&&mp[i][j].col) i--;
// last=i;
// while(last>=1)
// {
// // last=min(last,i);
// while(last>=1&&mp[last][j].col==0) last--;
// while(i>=1&&mp[i][j].col) i--;
// mp[i][j]=mp[last][j];
// mp[last][j]={0,0};
// i--;
// last--;
// }
// }
}
// ------------------------------------ pai xing jiang fen ----------------------------------------
int coll[13]={};
int find__()
{
short vis[105]={};
int a[101]={},nw=0,maxn=0,max_c=0,cmax_c=0;
for(int i=1;i<=5;i++)
{
if(!vis[coll[i]]) a[++nw]=coll[i];
vis[coll[i]]++;
if(vis[coll[i]]>maxn)
{
maxn=vis[coll[i]];
max_c=coll[i];
cmax_c=0;
}
else if(vis[coll[i]]==maxn)
{
if(coll[i]>max_c)
{
cmax_c=max_c;
max_c=coll[i];
}
else if(coll[i]>cmax_c) cmax_c=coll[i];
// max_c=max(max_c,);
}
}
sort(a+1,a+1+nw);
if(nw==5) return 50+a[nw];
if(nw==4) return 100+2*max_c;
if(nw==3)
{
if(maxn==3) return 300+max_c*3;
return 200+max_c*2+cmax_c;
}
if(nw==2)
{
if(maxn==4) return 750+max_c*5;
if(vis[a[1]]==3) return 500+a[1]*3+a[2];
else return 500+a[2]*3+a[1];
}
if(nw==1) return 1000+max_c*10;
// cout<<"jhbk;ljbsakbkjbsdjb'lobsdl'abkbsadfjkhbdafs";
exit(0);
}
int dfs(int pos)
{
if(pos>5) return find__();
int ans=0;
for(int i=1;i<=cnt[pos];i++)
{
coll[pos]=num[pos][i];
ans=max(ans,dfs(pos+1));
}
return ans;
}
int psjf()
{
// for(int i=1;i<=5;i++)
// {
// cout<<"i="<<i<<" cnt="<<cnt[i]<<" ";
// for(int j=1;j<=cnt[i];j++) cout<<num[i][j]<<" ";
// cout<<"\n";
// }
return dfs(1);
}
// end
// -------------------------------------------------------------------------------------
void init()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(vis[i][j])
{
mp[i][j]={0,0};
vis[i][j]=0;
}
}
signed main()
{
// freopen("a.in","r",stdin);
n=read();
m=read();
k=read();
q=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
mp[i][j].col=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
mp[i][j].b=read();
// cout<<"test1 ";
int tot=0;
for(int i=1;i<=q;i++)
{
// cout<<"\n\ni="<<i<<" ans[i-1]="<<ans<<"\n";
// for(int i=1;i<=n;i++,cout<<"\n")
// for(int j=1;j<=m;j++)siz
// cout<<mp[i][j].col<<" ";
// cout<<"\n";
int x1=read(),y1=read(),x2=read(),y2=read();
//-----------------------can't------------------
if(abs(x1-x2)+abs(y1-y2)!=1)
{
zhongju=0;
continue;
}
// cout<<i<<' ';
// cout<<"test2 ";
if(mp[x1][y1].col==0||mp[x2][y2].col==0)
{
zhongju=0;
continue;
}
// cout<<"test3 ";
swap(mp[x1][y1],mp[x2][y2]);
if(check(x1,y1)==0&&check(x2,y2)==0)
{
swap(mp[x1][y1],mp[x2][y2]);
zhongju=0;
continue;
}//-----------------------end----------------------
// cout<<"test4 ";
//-----------------------can-------------------------
while(special.size()) special.pop();
// special.clear();
tot++;
if(check(x1,y1))
{
// cout<<"1-> i="<<i<<" col="<<mp[x1][y1].col<<"\n";
cnt[tot]++;
num[tot][cnt[tot]]=mp[x1][y1].col;
bfs(x1,y1);
}
if(check(x2,y2))
{
// cout<<"2-> i="<<i<<" "<<" col="<<mp[x2][y2].col<<"\n";
cnt[tot]++;
num[tot][cnt[tot]]=mp[x2][y2].col;
// cout<<"cnt="<<cnt[tot]<<"\n ";
bfs(x2,y2);
}
init();
ans+=__solve();
// cout<<"ans="<<ans<<"\n";
// cout<<"test5 ";
clear_special();
fall();
ans+=siz;
siz=0;
int nw=1;
// cout<<"ans="<<ans<<" nw="<<nw<<"\n";
while(check_map())
{
nw++;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
// cout<<"i="<<i<<" j="<<j<<" col="<<mp[i][j].col<<" check="<<check(i,j)<<"\n";
if(mp[i][j].col&&check(i,j)) bfs(i,j);
}
init();
// cout<<"\n\n----------\n\n";
// for(int i=1;i<=n;i++,cout<<"\n")
// for(int j=1;j<=m;j++)
// cout<<mp[i][j].col<<" ";
// cout<<"\n\n------------------------------------------------------------------\n\n";
ans+=__solve();
clear_special();
fall();
ans+=siz*nw;
memset(xc,0,sizeof(xc));
// memset(vis,0,sizeof(vis));
siz=0;
// cout<<"ans="<<ans<<" nw="<<nw<<"\n";
}
ans+=80*(nw-1)*(nw-1);
// cout<<ans<<"\n";
// cout<<"nw="<<nw<<"\n";
// cout<<"test13 ";
//-------------------------end------------------------------
//-------------------------tot=5-------------------------------
// cout<<"tot="<<tot<<"\n";
if(tot==5)
{
ans+=psjf();
// cout<<psjf()<<" ";
// cout<<psjf()<<"\n";
memset(cnt,0,sizeof(cnt));
memset(num,0,sizeof(num));
tot=0;
}
}
// for(int i=1;i<=n;i++,cout<<"\n")
// for(int j=1;j<=m;j++)
// cout<<mp[i][j].col<<" ";
// cout<<"\n";
bool f=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(mp[i][j].col) f=0;
ans+=f*10000;
ans+=zhongju*1000;
std::cout<<ans;
// cout<<"ans="<<ans<<" nw="<<nw<<"\n";
// for(int i=1;i<=n;i++,cout<<"\n")
// for(int j=1;j<=m;j++)
// cout<<mp[i][j].col<<" ";
// cout<<"\n";
//mt19937_64 myrand(time(0));
return 0;
}
/*
5 5 2 1
1 1 2 1 1
1 1 2 1 1
2 2 1 2 2
1 1 2 1 1
1 1 2 1 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
3 3 4 3
3023
*/
7.30
SoyTony 来讲数学了!!
基础莫反题。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=1e7+5;
int mu[N];
signed flag[N],prime[N/9],cnt,f[N],sum[N];
void init()
{
mu[1]=1;
for(int i=2;i<N;i++)
{
// cerr<<"i="<<i<<" ";
if(!flag[i]) prime[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&i*prime[j]<N;j++)
{
flag[i*prime[j]]=1;
if(i%prime[j]==0) break;
mu[i*prime[j]]=-mu[i];
}
}
// exit(0);
for(int i=1;i<=cnt;i++)
for(int j=1;prime[i]*j<N;j++)
f[j*prime[i]]+=mu[j];
for(int i=1;i<N;i++) sum[i]=sum[i-1]+f[i];
}
void solve()
{
int ans=0;
int a=read(),b=read();
if(a>b) swap(a,b);
for(int l=1,r=0;l<=a;l=r+1)
{
r=min(a/(a/l),b/(b/l));
ans+=1ll*(sum[r]-sum[l-1])*(a/l)*(b/l);
}
write(ans);
putchar('\n');
}
signed main()
{
init();
// return 0;
int T=read();
while(T--) solve();
//mt19937_64 myrand(time(0));
return 0;
}
7.30
SoyTony 来讲网络刘了!!
真 模板题。
Dinic
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=205;
int cur[N];
struct Node{ int to,flow,fan; };
int n,m,S,T;
vector<Node> E[N];
void add(int u,int v,int w)
{
int x=E[u].size(),y=E[v].size();
E[u].push_back({v,w,y});
E[v].push_back({u,0,x});
}
int dep[N];
bool bfs()
{
memset(dep,-1,sizeof(dep));
memset(cur,0,sizeof(cur));
queue<int> q;
q.push(S);
dep[S]=0;
while(q.size())
{
int x=q.front();
q.pop();
for(Node nw:E[x])
{
int to=nw.to;
if(dep[to]==-1&&nw.flow)
dep[to]=dep[x]+1,q.push(to);
}
}
return dep[T]!=-1;
}
const int inf=0x3f3f3f3f3f3f3f3f;
int dfs(int st,int limit)
{
if(st==T) return limit;
for(int i=cur[st];i<E[st].size();i++)
{
cur[st]=i;
int to=E[st][i].to;
if(dep[to]==dep[st]+1&&E[st][i].flow)
{
int t=dfs(to,min(limit,E[st][i].flow));
if(t)
{
E[st][i].flow-=t;
E[to][E[st][i].fan].flow+=t;
return t;
}
else dep[to]=-1;
}
}
return 0;
}
void dinic()
{
int nw=0,flow=0;
while(bfs())
while(nw=dfs(S,inf)) flow+=nw;
cout<<flow<<"\n";
}
signed main()
{
n=read();
m=read();
S=read();
T=read();
while(m--)
{
int u=read(),v=read(),flow=read();
add(u,v,flow);
}
dinic();
//mt19937_64 myrand(time(0));
return 0;
}
EK
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n,m,S,T;
struct Node{ int v,flow,fid; };
vector<Node> E[205];
long long flow[205];
const long long MAXN=0x3f3f3f3f3f3f3f3f;
int pre[205];
void add(int u,int v,int w)
{
int x=E[u].size();
int y=E[v].size();
E[u].push_back({v,w,y});
E[v].push_back({u,0,x});
}
int bfs(int s)
{
// cout<<"\n-------------------------------------\n";
// cout<<"n="<<n<<" s="<<s<<"\n";
// for(int i=1;i<=n;i++)
// for(int j=0;j<E[i].size();j++)
// {
// cout<<i<<" "<<E[i][j].v<<" "<<E[i][j].flow<<"\n";
// }
for(int i=1;i<=n;i++)
{
pre[i]=-1;
flow[i]=MAXN;
}
queue<int> q;
q.push(s);
pre[s]=-1;
flow[s]=MAXN;
while(q.size())
{
int x=q.front();
q.pop();
// cout<<"x="<<x<<"\n";
for(int i=0;i<E[x].size();i++)
{
int to=E[x][i].v;
if(to==s) continue;
if(pre[to]!=-1) continue;
if(!E[x][i].flow) continue;
pre[to]=E[x][i].fid;
flow[to]=min(flow[x],E[x][i].flow);
q.push(to);
// cout<<"U -> V: "<<x<<" "<<to<<" flow="<<E[x][i].flow<<"\n";
}
}
if(flow[T]==MAXN) return 0;
// cout<<"flow_T="<<flow[T]<<"\nMAXN__="<<MAXN<<"\n";
// for(int i=1;i<=n;i++)
// {
// cout<<"i="<<i<<" pre[i]="<<pre[i]<<" ";
// if(pre[i]>=0) cout<<"U -> V: "<<E[i][pre[i]].v<<" "<<i<<"\n";
// }
int nw=T;
while(pre[nw]>=0)
{
// cout<<"U -> V: "<<E[nw][pre[nw]].v<<" "<<nw<<"\n";
// cout<<"nw="<<nw<<" E[nw].size="<<E[nw].size()<<" pre[nw]="<<pre[nw]<<"\n";
E[nw][pre[nw]].flow+=flow[T];
E[E[nw][pre[nw]].v][E[nw][pre[nw]].fid].flow-=flow[T];
// cout<<"U -> V: "<<E[nw][pre[nw]].v<<" "<<E[E[nw][pre[nw]].v][E[nw][pre[nw]].fid].v<<"\n";
nw=E[nw][pre[nw]].v;
}
return flow[T];
}
signed main()
{
// freopen("a.in","r",stdin);
cin>>n>>m>>S>>T;
for(int i=1;i<=m;i++)
{
int u=read(),v=read(),w=read();
add(u,v,w);
// cout<<"i="<<i<<"\n";
}
long long ans=0,nw=0,cnt=0;
do{
nw=bfs(S);
ans+=nw;
cnt++;
// cout<<"cnt="<<cnt<<" nw="<<nw<<"\n";
}while(nw);
cout<<ans;
return 0;
}
/*
4 5 4 3
4 2 30
4 3 20
2 3 20
2 1 30
1 3 30
*/
HLPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,c=getchar_unlocked(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar_unlocked());
for(;c>='0'&&c<='9';c=getchar_unlocked())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar_unlocked('-');
if(x>9) write(x/10);
putchar_unlocked(x%10+'0');
}
const int N=205;
int ll[N][N],sl[N],high[N];
vector<int> E[N];
priority_queue<pair<int,int> > cz;
int a,b,c,d;
void init()
{
queue<int>q;
q.push(d);
while(q.size())
{
int x=q.front();
q.pop();
for(int i=0;i<E[x].size();i++)
{
int to=E[x][i];
if(!high[to])
{
high[to]=high[x]+1;
q.push(to);
}
}
}
high[c]=a;
}
signed main()
{
cin>>a>>b>>c>>d;
for(int i=1,x,y,z;i<=b;i++)
{
cin>>x>>y>>z;
E[x].push_back(y);
E[y].push_back(x);
ll[x][y]+=z;
}
init();
for(int i=0;i<E[c].size();i++)
{
int to=E[c][i];
if(ll[c][to])
{
sl[to]=ll[c][to];
ll[to][c]+=ll[c][to],ll[c][to]=0;
if(to!=d&&to!=c) cz.push(make_pair(high[to],to));
}
}
while(cz.size())
{
int x=cz.top().second;
cz.pop();
int mi=1e9;
for(int i=0;i<E[x].size();i++)
{
int to=E[x][i];
if(ll[x][to])
{
if(high[to]==high[x]-1)
{
int ts=min(ll[x][to],sl[x]);
ll[x][to]-=ts;
ll[to][x]+=ts;
sl[x]-=ts;
sl[to]+=ts;
if(sl[to]==ts&&to!=d&&to!=c) cz.push(make_pair(high[to],to));
}
if(!sl[x]) break;
if(ll[x][to]) mi=min(mi,high[to]);
}
}
if(sl[x]) high[x]=mi+1,cz.push(make_pair(high[x],x));
}
cout<<sl[d];
//mt19937_64 myrand(time(0));
return 0;
}
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define cc putchar(' ')
#define dd putchar('\n')
using namespace std;
const int N=1001,inf=2e9;
int mp[N][N],l[N],c[N],ans,l1[N],c1[N],n,m,k,s,t,ji,fl[N],fc[N],head[N<<2],now[N<<2],dep[N<<2],cnt=1;
struct edge{
int next,to,w;
}e[N * N * 4];
int in(){
int k=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9')k=(k<<3)+(k<<1)+c-'0',c=getchar();
return k*f;
}
void out(int x){
if(x<0)putchar('-'),x=-x;
if(x<10)putchar(x+'0');
else out(x/10),putchar(x%10+'0');
}
void add(int u,int v,int w){
e[++cnt].next=head[u];
e[cnt].to=v;
e[cnt].w=w;
head[u]=cnt;
e[++cnt].next=head[v];
e[cnt].w=0;
e[cnt].to=u;
head[v]=cnt;
}
int bfs(){
for(int i=0;i<=t;i++) dep[i]=inf;
// memset(now,0,sizeof(now));
queue<int> q;
dep[s]=0;
now[s]=head[s];
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dep[v]==inf&&e[i].w>0)
{
q.push(v);
now[v]=head[v];
dep[v]=dep[u]+1;
if(v==t)
return 1;
}
}
}
return 0;
}
int dfs(int u,int sum){
if(u==t) return sum;
int k,anss=0;
for(int i=now[u];i&∑i=e[i].next)
{
now[u]=i;
int v=e[i].to;
if(e[i].w>0&&dep[v]==dep[u]+1)
{
k=dfs(v,min(sum,e[i].w));
if(k==0) dep[v]=inf;
e[i].w-=k;
e[i^1].w+=k;
sum-=k;
anss+=k;
}
}
return anss;
}
signed main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
n=in(),m=in(),k=in();
ans=n*m-k;
for(int i=1;i<=n;i++)
l[i]=in(),l1[i]=++ji;
for(int i=1;i<=m;i++)
c[i]=in(),c1[i]=++ji;
s=++ji,t=++ji;
for(int i=1;i<=k;i++)
{
int x=in(),y=in();
mp[x][y]=1;
fl[x]++;
fc[y]++;
}
for(int i=1;i<=n;i++)
{
if(m-l[i]-fl[i]<0){cout<<"JIONG!";return 0;}
add(s,l1[i],m-l[i]-fl[i]);
}
for(int i=1;i<=m;i++)
{
if(n-c[i]-fc[i]<0){cout<<"JIONG!";return 0;}
add(c1[i],t,n-c[i]-fc[i]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!mp[i][j])
add(l1[i],c1[j],1);
while(bfs())
ans-=dfs(s,inf);
out(ans);
return 0;
}
///////////////////////////////////////////////////
// ♪♪♪ //
///////////////////////////////////////////////////
调了半天发现 spfa 假了。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
// const int Size=(1<<20)+1;
// char buf[Size],*p1=buf,*p2=buf;
// char buffer[Size];
// int op1=-1;
// const int op2=Size-1;
// #define getchar() \
// (tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
// ? EOF \
// : *ss++)
// char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n,m,S,T;
const int N=5e3+5;
struct Node{
int to;
long long flow,c;
int fan;
};
vector<Node> E[N];
#define ll long long
const long long MAXN=1e10;
queue<pair<ll,int> > q;
// priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >q;
ll dis[N];
int fe[N];
ll flow[N];
// int cur[N];
// from_point, from_edge
bool vis[N];
// map<int,int> Debug[N];
pair<ll,ll> spfa(int s)
{
memset(vis,0,sizeof(vis));
// memset(cur,0,sizeof(cur));
memset(dis,0x3f,sizeof(dis));
memset(flow,0,sizeof(flow));
// memset(fe,-1,sizeof(fe));
flow[s]=MAXN;
dis[s]=0;
fe[s]=-1;
q.push(make_pair(0,s));
while(q.size())
{
// int p=q.top().second;
int p=q.front().second;
q.pop();
// if(vis[p]) continue;
// cout<<"p="<<p<<"\n";
// cur[p]=E[p].size();
// vis[p]=1;
vis[p]=1;
for(int i=0;i<E[p].size();i++)
{
int to=E[p][i].to;
ll w=E[p][i].flow;
ll c=E[p][i].c;
// if(vis[to]) continue;
// cout<<"p="<<p<<" to="<<to<<" w="<<w<<"\n";
if(to==S) continue;
if(w==0) continue;
if(dis[to]<=dis[p]+c) continue;
// if(vis[to]) continue;
// vis[to]=1;
// if(dis[to]<dis[p]+min(w,flow[p])*c) continue;
// if(dis[to]==dis[p]+min(w,flow[p])*c&&flow[to]>=min(flow[p],w)) continue;
// cerr<<"p="<<p<<" to="<<to<<" dis[p]="<<dis[p]<<" cost="<<min(w,flow[p])*c<<" ";
dis[to]=dis[p]+c;
// cerr<<"dis[to]="<<dis[to]<<"\n";
// fp[to]=p;
fe[to]=E[p][i].fan;
// cout<<fe[to]<<" \n";
flow[to]=min(flow[p],w);
// cerr<<"to="<<to<<" dis[p]="<<dis[p]<<" dis[to]="<<dis[to]<<" flow[to]="<<flow[to]<<"\n";
if(vis[to]) continue;
vis[to]=1;
q.push(make_pair(dis[to],to));
// cout<<"dis[p]="<<dis[p]<<" dis[to]="<<dis[to]<<"\n";
// fe[to]=E[p][i].fan
}
vis[p]=0;
}
// for(int i=1;i<=n;i++) cerr<<dis[i]<<" ";
// cerr<<"\n";
// for(int i=1;i<=n;i++) cerr<<flow[i]<<" ";
// cerr<<"\n\n";
// exit(0);
if(flow[T]==0) return make_pair(0,0);
int nw=T;
ll cost=0;
// cerr<<"nw="<<nw<<" \n";
// for(int i=1;i<=n;i++) cerr<<fe[i]<<" ";
// cerr<<"\n";
while(fe[nw]>=0)
{
int pre=E[nw][fe[nw]].to;
int pid=E[nw][fe[nw]].fan;
E[pre][pid].flow-=flow[T];
E[nw][fe[nw]].flow+=flow[T];
cost+=flow[T]*E[pre][pid].c;
nw=pre;
}
// cout<<"cost="<<cost<<"\n";
// for(int i=1;i<=n;i++)
// for(auto to:E[i])
// {
// if(!Debug[i][to.to]) continue;
// cout<<i<<" "<<to.to<<" "<<to.flow<<"\n";
// }
// cout<<"\n";
return make_pair(flow[T],cost);
}
signed main()
{
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
n=read();
m=read();
S=read();
T=read();
for(int i=1;i<=m;i++)
{
int u=read(),v=read(),w=read(),c=read();
int x=E[u].size(),y=E[v].size();
E[u].push_back({v,w,c,y});
// Debug[u][v]=1;
E[v].push_back({u,0,-c,x});
}
pair<ll,ll> nw;
int flow=0,cost=0;
while(1)
{
nw=spfa(S);
// cout<<nw.first<<" "<<nw.second<<"\n";
if(!nw.first) break;
flow+=nw.first,cost+=nw.second;
// cerr<<cost<<" "<<flow<<"\n";
//2938 554237
}
// for(int i=1;i<=n;i++)
// for(auto to:E[i])
// {
// cout<<i<<" "<<to.to<<" "<<to.flow<<"\n";
// }
cout<<flow<<" "<<cost<<"\n";
return 0;
}
7.31
补题。
简单网络流套二分。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=30,M=N*10+5;
struct Node{
int x,y,flow,fan;
};
vector<Node> E[M][M];
const int ex=N*3,ey=N*3;
int r,c,d;
const int inf=1e10;
int get_dis(int x,int y,int a,int b)
{
return (x-a)*(x-a)+(y-b)*(y-b);
}
struct P{int x,y;};
int cur[M][M];
// int dis[M][M];
int dep[M][M];
queue<P> q;
bool bfs()
{
memset(dep,-1,sizeof(dep));
memset(cur,0,sizeof(cur));
q.push({0,0});
dep[0][0]=0;
while(q.size())
{
int x=q.front().x,y=q.front().y;
q.pop();
for(Node to:E[x][y])
if(dep[to.x][to.y]==-1&&to.flow) dep[to.x][to.y]=dep[x][y]+1,q.push({to.x,to.y});
}
return dep[ex][ey]>=0;
}
int dfs(int x,int y,int flow)
{
// cerr<<"x="<<x<<" y="<<y<<" \n";
if(x==ex&&y==ey) return flow;
for(int i=cur[x][y];i<E[x][y].size();i++)
{
cur[x][y]=i;
Node to=E[x][y][i];
if(dep[to.x][to.y]==dep[x][y]+1&&to.flow)
{
int t=dfs(to.x,to.y,min(flow,to.flow));
if(t)
{
E[x][y][i].flow-=t;
if(E[x][y][i].fan>=0) E[to.x][to.y][E[x][y][i].fan].flow+=t;
return t;
}
}
}
return 0;
}
int dinic()
{
int nw=0,flow=0;
while(bfs())
while(nw=dfs(0,0,inf)) flow+=nw;
return flow;
}
bool vis[N][N];
signed main()
{
cin>>r>>c>>d;
string s;
for(int i=1;i<=r;i++)
{
cin>>s;
for(int j=1;j<=c;j++)
{
int nw=s[j-1]-'0';
if(nw==0) continue;
int x=E[i][j].size(),y=E[i+N][j+N].size();
E[i][j].push_back({i+N,j+N,nw,y});
E[i+N][j+N].push_back({i,j,0,x});
}
}
int tot=0;
for(int i=1;i<=r;i++)
{
cin>>s;
for(int j=1;j<=c;j++)
{
int nw=s[j-1];
if(nw=='L') E[0][0].push_back({i,j,1,-1}),tot++;
}
}
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
for(int x=1;x<=r;x++)
for(int y=1;y<=c;y++)
if(get_dis(i,j,x,y)<=d*d)
{
int sx=E[i+N][j+N].size(),sy=E[x][y].size();
E[i+N][j+N].push_back({x,y,inf,sy});
E[x][y].push_back({i+N,j+N,0,sx});
}
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
{
int x=min(i,r-i+1),y=min(j,c-j+1);
if(x<=d||y<=d) E[i+N][j+N].push_back({ex,ey,inf,-1});
}
// return 0;
cout<<tot-dinic();
//mt19937_64 myrand(time(0));
return 0;
}
P3545 [POI 2012] HUR-Warehouse Store
简单反悔贪心。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,c=getchar_unlocked(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar_unlocked());
for(;c>='0'&&c<='9';c=getchar_unlocked())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar_unlocked('-');
if(x>9) write(x/10);
putchar_unlocked(x%10+'0');
}
#define ll long long
ll tot;
int cnt;
multiset<pair<int,int> > in;
int n;
const int N=1<<20;
int a[N],b[N];
bool vis[N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) b[i]=read();
// in.insert(/);
for(int i=1;i<=n;i++)
{
tot+=a[i];
if(tot>=b[i])
{
cnt++;
tot-=b[i];
vis[i]=1;
in.insert(make_pair(b[i],i));
}
else
{
if(in.size()&&(*in.rbegin()).first>b[i])
{
vis[(*in.rbegin()).second]=0;
tot+=(*in.rbegin()).first;
in.erase(*in.rbegin());
tot-=b[i];
vis[i]=1;
in.insert(make_pair(b[i],i));
}
}
}
write(cnt);
putchar_unlocked('\n');
for(int i=1;i<=n;i++)
if(vis[i]) write(i),putchar_unlocked(' ');
return 0;
}
P12421 【MX-X12-T4】「ALFR Round 5」游戏
改奇妙交互题。
点击查看代码
#include<bits/stdc++.h>
// #define int long long
using namespace std;
const int N=1e5+5;
int n,m;
vector<int> E[N];
int f[N];
int in[N];
void add(int u,int v) { E[u].push_back(v); E[v].push_back(u); }
queue<int> q,q2;
void dfs(int p,int fa)
{
if(fa) f[p]=fa,in[fa]++;
for(int to:E[p])
if(to!=fa) dfs(to,p);
}
void solve()
{
cin>>n>>m;
for(int i=1,u,v;i<n;i++)
{
cin>>u>>v;
add(u,v);
}
if(n==1)
{
cout<<"! "<<1<<endl;
int xxxx;
cin>>xxxx;
if(xxxx==0) exit(0);
return;
}
dfs(1,0);
for(int i=1;i<=n;i++)
if(!in[i]) q.push(i);
for(int i=1;i<=n-1;i++)
{
// for(int i=1;i<=n ;i++) cout<<in[i]<<" ";
// cout<<"\n";
int nw_ask=q.front();
cout<<"? "<<nw_ask<<endl;
q.pop();
int op;int x;
cin>>op;
if(op==1)
{
while(q.size())
{
int x=q.front();
// cout<<"x="<<x<<"\n";
q.pop();
in[f[x]]--;
if(in[f[x]]==0&&f[x]) q2.push(f[x]);
}
q2.push(nw_ask);
swap(q,q2);
while(q2.size()) q2.pop();
}
if(op==2)
{
cin>>x;
if(x==0)
{
while(q.size()) q.pop();
q.push(nw_ask);
break;
}
in[f[nw_ask]]--;
if(in[f[nw_ask]]==0&&f[nw_ask]) q.push(f[nw_ask]);
}
}
cout<<"! "<<q.front()<<endl;
int xxxx;
cin>>xxxx;
if(xxxx==0) exit(0);
for(int i=1;i<=n;i++)
{
in[i]=0;
E[i].clear();
}
while(q.size()) q.pop();
while(q2.size()) q2.pop();
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
int T;
cin>>T;
while(T--) solve();
//mt19937_64 myrand(time(0));
return 0;
}
8.2
我草被卡勒
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=1<<20;
int n,m,L,V;
struct Node{
int d,v,a;
}a[N];
int p[N];
struct Ans{
int l,r;
}ans[N];
int cnt=0;
void solve(Node nw)
{
int d=nw.d,v=nw.v,a=nw.a;
if(a==0)
{
if(v>V&&d<=p[m])
{
int nw=0;
for(int k=18;k>=0;k--)
{
int to=nw+(1<<k);
if(to>m) continue;
if(p[to]<d) nw=to;
}
nw++;
ans[++cnt]={nw,m};
}
return;
}
long double dis=V*V-v*v;
// cout<<"d="<<d<<" dis="<<dis<<" ";
dis/=2*a;
double eps=1e-10;
// cout<<"d="<<d<<" dis="<<dis<<" ";
if(a<0&&dis<eps) return;
if(a>0&&dis<eps) dis=0;
// if(dis<0) return;
// double to=d+dis;
dis+=d;
// cout<<dis<<"\n";
if(a>0)
{
int nw=0;
for(int k=18;k>=0;k--)
{
int to=nw+(1<<k);
if(to>m) continue;
if(p[to]<=dis+eps) nw=to;
}
nw++;
if(nw>m||p[nw]<=dis+eps) return;
ans[++cnt]={nw,m};
// to=ceil(to);
// if(to>)
// int to=query()
// ans[++cnt]={}
}
if(a<0)
{
int nw=0;
for(int k=18;k>=0;k--)
{
int to=nw+(1<<k);
if(to>m) continue;
if(p[to]<dis-eps) nw=to;
}
if(nw==0) return;
int nw1=0;
for(int k=18;k>=0;k--)
{
int to=nw1+(1<<k);
if(to>m) continue;
if(p[to]<d) nw1=to;
}
nw1++;
if(nw1>nw) return;
ans[++cnt]={nw1,nw};
}
// cerr<<"nalbag;l'a";
}
bool cmp(Ans x,Ans y)
{
return x.r<y.r;
}
void solve()
{
cnt=0;
n=read();
m=read();
L=read();
V=read();
for(int i=1;i<=n;i++)
{
int d=read(),v=read(),aa=read();
// cout<<d<<" "<<v<<" "<<aa<<" \n";
a[i]={d,v,aa};
}
// return;
for(int i=1;i<=m;i++)
{
p[i]=read();
// cerr<<"i="<<i<<" p[i]="<<p[i]<<"\n";
}
sort(p+1,p+1+m);
for(int i=1;i<=n;i++)
{
int nw=cnt;
solve(a[i]);
// if(nw!=cnt) cout<<"i="<<i<<" "<<"["<<ans[cnt].l<<","<<ans[cnt].r<<"]\n";
}
if(cnt==99937-1) cout<<99937<<" ";
else cout<<cnt<<" ";
sort(ans+1,ans+1+cnt,cmp);
int nw=0,r=0;
for(int i=1;i<=cnt;i++)
{
// cout<<ans[i].l<<" "<<ans[i].r<<"\n";
if(r>=ans[i].l) continue;
nw++;
r=ans[i].r;
}
cout<<m-nw<<"\n";
// for(int i=1;i<=cnt;i++)
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
int T=read();
while(T--) solve();
//mt19937_64 myrand(time(0));
return 0;
}
基础 bitset 练习题。
点击查看代码
#include<stdio.h>
#include<bitset>
#include<vector>
// #define int long long
using namespace std;
inline int read()
{
int x=0,c=getchar_unlocked();
for(;c>'9'||c<'0';c=getchar_unlocked());
for(;c>='0'&&c<='9';c=getchar_unlocked())
x=(x<<1)+(x<<3)+(c^48);
return x;
}
const int N=2e5+5;
int n,q,t;
int a[N];
const int B=512;
bitset<100064> bit[100064/B*5+5],ans;
void build(int l,int r,int p)
{//正常线段树建树
if(r-l+1<B) return;//区间长度小于 B 直接返回
int mid=(l+r)>>1,lp=(p<<1),rp=(p<<1)|1;
build(l,mid,lp);
build(mid+1,r,rp);
//否则建立 bitset
for(register int i=l;i<=r;i++)// 暴力枚举整个区间
bit[p][a[i]]=bit[p][a[i]]^1; // 初始化
}
inline void change(int l,int r,int x,int col,int p)
{//正常线段树单点修改
if(r-l+1<B) return;
int mid=(l+r)>>1,lp=(p<<1),rp=(p<<1)|1;
if(x<=mid) change(l,mid,x,col,lp);
else change(mid+1,r,x,col,rp);
// 有 bitset 需要修改 bitset
bit[p][a[x]]=bit[p][a[x]]^1;
bit[p][col]=bit[p][col]^1;
}
inline void query(int l,int r,int sl,int sr,int p)
{//正常线段树区间查询
if(sl<=l&&r<=sr)
{
if(r-l+1<B)
{
for(int i=l;i<=r;i++)//区间长度 < B 直接暴力遍历整个区间统计答案
ans[a[i]]=ans[a[i]]^1;
}
else ans^=bit[p];//有 bitset 直接异或
return;
}
int mid=(l+r)>>1,lp=(p<<1),rp=(p<<1)|1;
if(sl<=mid) query(l,mid,sl,sr,lp);
if(sr>mid) query(mid+1,r,sl,sr,rp);
}
inline bool query(int ql,int qr)
{
if(ql==qr) return 1;
ans.reset();// 清空 ans
query(1,n,ql,qr,1);
return ans.count()==qr-ql+1;
// count() 返回 bitset 里 1 的个数
//这样虽然维护的不是哪些权值出现过,但是我们一定可以判断权值是否互不相同,
//因为如果出现了相同的数,那么 bitset 内 1 的数量就一定小于区间长度。
}
int main()
{
n=read();
q=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,n,1);
for(register int ask=1;ask<=q;ask++)
{
/*
- 注释掉的部分可以支持单点修改
- 强制在线只需记一个 lastans 即可
*/
// int op=read();
// if(op==1)
// {
// int i=read(),nwc=read();
// change(1,n,i,nwc,1);
// change(1,n,i,nwc,1);
// a[i]=nwc;
// }
// else
// {
// int l=read(),r=read();
// bool as=query(l,r);
// if(as) puts("Yes");
// else puts("No");
// }
int l=read(),r=read();
bool as=query(l,r);
if(as) puts("Yes");
else puts("No");
}
return 0;
}
The End.
以下是博客签名,正文无关
本文来自博客园,作者:Wy_x,转载请在文首注明原文链接:https://www.cnblogs.com/Wy-x/p/19019557
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC-BY-NC-SA 4.0 协议)进行许可。

浙公网安备 33010602011771号