zoukankan      html  css  js  c++  java
  • [考试反思]0608四校联考第二轮day2:消耗

    还是退役的分。

    题不太好。非常卡常。几乎没部分分。$T3$毫无意义。

    $T1$是若干个讲过的原题组合而成的,然而好像很麻烦不是很想写,就先看$T2$了。

    $T2$感觉像原题然而并不是。然后一直在尝试想。

    没花多少时间想出了$O(n^2)$的暴力。然后花了挺长时间搞出了$O(nlog^2n)$的做法。

    对拍都挂上了。本来抱着$80$打底卡常也许能$AC$的念想。然后被毒瘤卡常了只剩下$n^2$的分。

    $T3$惯例神仙题,并没有时间去写$10pts$的暴力(又难写又分少)

    这一轮两天加起来的成绩在总榜上不算特别低,但还是联赛比我低的把我翻了联赛比我高的我翻不动,所以又退役了。

    也只能尽力去考吧,剩下的交给出题人和出数据的和评测机。

    T1:endless

    大意:对于所有平方串$[i,i+2l-1]$,对于所有$jin [i,i+l-1]$将$(j,j+l)$连上权值为$w_l$的边。求最小生成森林。$n le 3 imes 10^5$

    生成树算法就那么几个,平时常用的也就是更少了,这题$Boruvka$显然不可行,于是考虑$Kruscal$

    所以还是从小到大枚举边权,然后看能连上多少边。

    那么对于特定长度处理有哪些点对之间能连边这已经是个老问题了,设立哨兵节点求相邻哨兵的$lcp,lcs$然后区间连边即可。

    区间连边这种东西这里写的是倍增并查集。查询$[a,a+2^i),[b,b+2^i]$两个区间是否已经完全对位合并。

    如果合并过了就直接返回没什么问题,否则就递归下去合并直到叶节点就做普通并查集合并,并且上传信息。

    会递归下去一定代表在这一轮里你会合并两个元素,所以总复杂度是$O(n ln n+n log n)$的。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ull unsigned long long
     4 const int S=333333;
     5 long long ans;int n,w[S],f[19][S],SA[2][S],rk[2][S],h[2][S],a[S],ST[2][19][S],lb[S],r[S];
     6 int find(int d,int x){return f[d][x]==x?x:f[d][x]=find(d,f[d][x]);}
     7 void get_SA(int*a,int*sa,int*rk,int*h,int o,int m=n){
     8     static int b[S],x[S],y[S];
     9     for(int i=1;i<=n;++i)b[i]=0,x[i]=a[i];
    10     for(int i=1;i<=n;++i)b[x[i]]++;
    11     for(int i=1;i<=n;++i)b[i]+=b[i-1];
    12     for(int i=1;i<=n;++i)sa[b[x[i]]--]=i;
    13     for(int len=1;len<=n;len<<=1){
    14         int num=0;
    15         for(int i=n-len+1;i<=n;++i)y[++num]=i;
    16         for(int i=1;i<=n;++i)if(sa[i]>len)y[++num]=sa[i]-len;
    17         for(int i=1;i<=m;++i)b[i]=0;
    18         for(int i=1;i<=n;++i)b[x[i]]++;
    19         for(int i=1;i<=m;++i)b[i]+=b[i-1];
    20         for(int i=n;i;--i)sa[b[x[y[i]]]--]=y[i];
    21         for(int i=1;i<=n;++i)y[i]=x[i],x[i]=0;
    22         x[sa[1]]=m=1;
    23         for(int i=2;i<=n;++i)x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+len]==y[sa[i-1]+len]?m:++m;
    24         if(m==n)break;
    25     }
    26     for(int i=1;i<=n;++i)rk[sa[i]]=i,y[i]=0;
    27     for(int i=1,k=0;i<=n;h[rk[i++]]=k,k-=k>0)while(a[i+k]==a[sa[rk[i]-1]+k])k++;
    28     for(int i=1;i<=n;++i)ST[o][0][i]=h[i];
    29     for(int i=1;i<19;++i)for(int j=1;j+(1<<i)-1<=n;++j)ST[o][i][j]=min(ST[o][i-1][j],ST[o][i-1][j+(1<<i-1)]);
    30 }
    31 int Min(int o,int l,int r){int b=lb[r-l+1];return min(ST[o][b][l],ST[o][b][r-(1<<b)+1]);}
    32 int lcs(int a,int b){if(rk[0][a]>rk[0][b])swap(a,b);return Min(0,rk[0][a]+1,rk[0][b]);}
    33 int lcp(int a,int b){a=n+1-a;b=n+1-b;if(rk[1][a]>rk[1][b])swap(a,b);return Min(1,rk[1][a]+1,rk[1][b]);}
    34 bool merge(int B,int x,int y,int w){
    35     if(find(B,x)==find(B,y))return 0;
    36     if(B==0){f[0][find(0,x)]=find(0,y),ans+=w;return 1;}
    37     if(!(merge(B-1,x,y,w)|merge(B-1,x+(1<<B-1),y+(1<<B-1),w)))return f[B][find(B,x)]=find(B,y),0;
    38     return 1;
    39 }
    40 int main(){
    41     freopen("endless.in","r",stdin);freopen("endless.out","w",stdout);
    42     for(int i=0;i<19;++i)for(int j=1<<i;j<2<<i&&j<S;++j)lb[j]=i;
    43     int t;cin>>t;while(t--){
    44         scanf("%d",&n);ans=0;
    45         for(int i=0;i<19;++i)for(int j=1;j+(1<<i)-1<=n;++j)f[i][j]=j;
    46         for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    47         get_SA(a,SA[0],rk[0],h[0],0);
    48         reverse(a+1,a+1+n);
    49         get_SA(a,SA[1],rk[1],h[1],1);
    50         for(int i=1;i+i<=n;++i)scanf("%d",&w[i]),r[i]=i;
    51         sort(r+1,r+1+(n>>1),[](int a,int b){return w[a]<w[b];});
    52         for(int _=1,l;l=r[_],_+_<=n;++_){
    53             for(int i=l;i+l<=n;i+=l){
    54                 int s=min(l,lcs(i,i+l)),p=min(l,lcp(i,i+l)),x=s+p-1,B;
    55                 if(x<l)continue; 
    56                 B=lb[x]; merge(B,i-p+1,i-p+1+l,w[l]); merge(B,i+s-(1<<B),i+l+s-(1<<B),w[l]);
    57             }
    58         }
    59         printf("%lld
    ",ans); for(int i=1;i<=n;++i)a[i]=0;
    60     }
    61 }
    View Code

    T2:图

    大意:给定$n$点无向图,不断进行:如果$a<b<c$且$ab$有边$ac$有边那么你会把$bc$也连上。求最终的图中用$n$种颜色染色,边两端点不同色方案数。$n,m le 10^6$

    一个小的结论是:对于点$i$,它所连出的所有边中比它大的点会构成完全图。

    也就是说$i$能到的点$x,y$,那么$x,y$也一定可以互相到达。

    我们用$set$维护每个点的出边,那么就会有一些继承关系。

    当前点$x$的出边会交给它能到达的所有点,但是仔细一想,只要交给$y=upperbound(x)$就可以了,因为这样$y$就能到达其它它能到达的点。

    然后$y$也就会继续交给其它点一直传递下去。这是没有问题的。

    所以就是启发式一发,每次到一个点的时候把自己删掉就好了。时间复杂度$O(nlog^2n)$。

    实际运行效率高于$O(nlogn)$的线段树合并

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int ans=1,n,m; set<int>s[1000005];
     4 int main(){
     5     freopen("graph.in","r",stdin);freopen("graph.out","w",stdout);
     6     scanf("%d%d",&n,&m);
     7     for(int i=1,a,b;i<=m;++i)scanf("%d%d",&a,&b),s[a].insert(b);
     8     for(int i=1,y;i<=n;++i){
     9         s[i].erase(i); y=*s[i].begin();
    10         ans=1ll*ans*(n-s[i].size())%998244353;
    11         if(s[i].size()>s[y].size())swap(s[i],s[y]);
    12         for(auto x:s[i])s[y].insert(x);
    13     }printf("%d",ans);
    14 }
    View Code

    T3:Light

    没啥意思的题。。。还是不讲了吧。(关键是我也没机会改出来了

    就是大力分类讨论,二分答案与贪心,带权并查集,考虑当前操作是否会影响后续操作。

    对着$std$写都写不对。我人都没了。存个代码吧。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define S 222
      4 #define pb push_back
      5 #define nxt(i,l) i==l-1?0:i+1
      6 #define cir(s,t,l) for(int i=s%l;i!=t;i=nxt(i,l))
      7 int t,n,a[S],b[S],has[S][S],share[S][S],bl[S],f[S],st[S]; vector<int>E[S],R;
      8 void reset(int n){for(int i=1;i<=n;++i)st[i]=0,f[i]=i;}
      9 int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
     10 void merge(int x,int y){if(find(x)!=find(y))st[f[f[x]]=f[y]]|=st[f[x]];}
     11 int pos(vector<int>&v,int x){for(int i=0;i<v.size();++i)if(v[i]==x)return i;return -1;}
     12 void cut(int e,int x){cerr<<e<<' '<<x<<endl;
     13     R=E[x]; int A=a[e],B=b[e],oA=pos(R,A),oB=pos(R,B),L=R.size();
     14     for(int i=1;i<=e+4;++i)has[x][i]=0; E[x].clear();
     15     cir(oA,(oB+1)%L,L)E[x].pb(R[i]),has[x][R[i]]=1;
     16     cir(oB,(oA+1)%L,L)E[e+1].pb(R[i]),has[e+1][R[i]]=1;
     17     E[x].pb(e+4); E[e+1].pb(e+4); has[x][e+4]=has[e+1][e+4]=1; share[x][e+1]=e+4;
     18     for(int i=1;i<=e;++i)share[i][e+1]=share[e+1][i]=share[x][i];
     19 }
     20 bool chk(int n){
     21     memset(has,0,sizeof has);memset(share,0,sizeof share);for(int i=1;i<=n+1;++i)E[i].clear();
     22     for(int i=1;i<5;++i)E[1].pb(i),has[1][i]=1;
     23     for(int i=1,x,y,A,B;A=a[i],B=b[i],x=y=0,i<=n;++i){
     24         for(int j=1;j<=i;++j)if(has[j][A]|has[j][B])(x?y:x)=j;
     25         if(!x)return 0; if(!y){cut(i,x);continue;}
     26         for(int j=1;j<=i+4;++j)bl[j]=0;
     27         for(auto z:E[x])bl[z]|=1;
     28         for(auto z:E[y])bl[z]|=2;
     29         bl[A]=bl[B]=0; reset(n+4);
     30         for(int j=i+1;j<=n;++j)if(a[j]>=i+4)merge(a[j],j+4);else if(bl[a[j]])st[j+4]|=1<<bl[a[j]]-1;
     31         for(int j=i+1;j<=n;++j)if(b[j]>=i+4)merge(b[j],j+4);else if(bl[b[j]])st[j+4]|=1<<bl[b[j]]-1;
     32         int ST=st[find(i+4)];
     33         if((ST&3)==3)return 0;
     34         if(ST^4){cut(i,!ST||ST&1?x:y);continue;}
     35         if(B!=share[x][y])swap(A,B);cerr<<n<<' '<<i<<' '<<"ohhh"<<endl;
     36         int C=1;while(bl[C]^3)C++;bl[C]=0;
     37         int Ax=pos(E[x],A),Bx=pos(E[x],B),Cx=(E[x],C),Ay=pos(E[y],A),By=pos(E[y],B),Cy=pos(E[y],C),sx=E[x].size(),sy=E[y].size(),t;
     38         if(nxt(Bx,sx)!=Cx&&nxt(Cx,sx)!=Bx)
     39             if(nxt(Ax,sx)==Bx)cir(Bx+1,Cx,sx)bl[E[x][i]]=0;
     40             else cir(Cx+1,Bx,sx)bl[E[x][i]]=0;
     41         if(nxt(By,sy)!=Cy&&nxt(Cy,sy)!=By)
     42             if(nxt(Ay,sy)==By)cir(By+1,Cy,sy)bl[E[y][i]]=0;
     43             else cir(Cy+1,By,sy)bl[E[y][i]]=0;
     44         reset(n+4);
     45         for(int j=i+1;j<=n;++j)if(a[j]>=i+4||a[j]!=B)merge(a[j],i+4);else if(bl[a[j]])st[j+4]|=1<<bl[a[j]]-1;
     46         for(int j=i+1;j<=n;++j)if(b[j]>=i+4||b[j]!=B)merge(b[j],i+4);else if(bl[b[j]])st[j+4]|=1<<bl[b[j]]-1;
     47         ST=st[find(B)];
     48         if(ST==1)cut(i,x);
     49         if(ST==2)cut(i,y);
     50         if(ST==3)return 0;
     51         if(!ST)cut(i,nxt(Bx,sx)!=Cx&&nxt(Cx,sx)!=Bx?y:x);
     52     }return 1;
     53 }
     54 int main(){freopen("light.in","r",stdin);cin>>t;while(t--){
     55     cin>>n;    for(int i=1;i<=n;++i)cin>>a[i]>>b[i];
     56     int l=0,r=n,m,a;
     57     while(m=l+r>>1,l<=r)if(chk(m))a=l=m,l++;else r=m-1;
     58     cout<<a<<endl;
     59 }}
     60 #include<bits/stdc++.h>
     61 using namespace std;
     62 struct dsu{
     63     vector<int>mask,p; int n;
     64     dsu(int n):n(n){
     65         mask.resize(n);p.resize(n);
     66         for(int i=0;i<n;++i)mask[i]=0,p[i]=i;
     67     }
     68     inline int find(int x){
     69         while(x!=p[x])x=p[x]=p[p[x]];
     70         return x;
     71     }
     72     inline bool unite(int x,int y){
     73         x=find(x); y=find(y);
     74         if(x==y)return 0;
     75         else return p[x]=y,mask[y]|=mask[x],1;
     76     }
     77 };
     78 int main(){freopen("light.in","r",stdin); int tt; cin>>tt; while(tt--){
     79     int n; cin>>n;
     80     vector<int>a(n),b(n);
     81     for(int i=0;i<n;++i)cin>>a[i]>>b[i],--a[i],--b[i];
     82     auto check=[&](int n){
     83         vector<vector<int>>seq(n+1);
     84         vector<vector<bool>>has(n+1,vector<bool>(n+4,0));
     85         vector<vector<int>>share(n+1,vector<int>(n+1,-1));
     86         for(int i=0;i<4;++i)seq[0].push_back(i),has[0][i]=1;
     87         auto put=[&](int i,int x){cerr<<i+1<<' '<<x+1<<endl;
     88             vector<int>polygon=seq[x];
     89             int id_a=-1,id_b=-1;
     90             for(int j=0;j<(int)polygon.size();++j){
     91                 if(a[i]==polygon[j])id_a=j;
     92                 if(b[i]==polygon[j])id_b=j;
     93             }
     94             for(int j=0;j<i+4;++j)has[x][j]=0;
     95             seq[x].clear();
     96             for(int j=id_a;;j=(j+1)%polygon.size()){
     97                 seq[x].push_back(polygon[j]);
     98                 has[x][polygon[j]]=1;
     99                 if(j==id_b)break;
    100             }
    101             seq[x].push_back(i+4);
    102             has[x][i+4]=1;
    103             for(int j=id_b;;j=(j+1)% polygon.size()){
    104                 seq[i+1].push_back(polygon[j]);
    105                 has[i+1][polygon[j]]=1;
    106                 if(j==id_a)break;
    107             }
    108             seq[i+1].push_back(i+4);
    109             has[i+1][i+4]=1;
    110             for(int j=0;j<=i;++j)share[i+1][j]=share[j][i+1]=share[x][j];
    111             share[x][i+1]=share[i+1][x]=i+4;
    112         };
    113         for(int i=0,x,y;x=y=-1,i<n;++i){
    114             for(int j=0;j<=i;++j)if(has[j][a[i]]&&has[j][b[i]])(x==-1?x:y)=j;
    115             if(x==-1)return 0;
    116             if(y==-1){put(i,x);continue;}
    117             vector<int>belong(i+4);
    118             for(auto j:seq[x])belong[j]|=1;
    119             for(auto j:seq[y])belong[j]|=2;
    120             belong[a[i]]=belong[b[i]]=0;
    121             dsu p(n+4);
    122             for(int j=i;j<n;++j){
    123                 if(a[j]<i+4){if(belong[a[j]])p.mask[j+4]|=1<<(belong[a[j]]-1);}
    124                 else p.unite(a[j],j+4);
    125                 if(b[j]<i+4){if(belong[b[j]])p.mask[j+4]|=1<<(belong[b[j]]-1);}
    126                 else p.unite(b[j],j+4);
    127             }
    128             int mask=p.mask[p.find(i+4)];
    129             if((mask&3)==3)return 0;
    130             if(mask&1)put(i,x);
    131             else if(mask&2)put(i,y);
    132             else if(!mask)put(i,x);
    133             else{cerr<<n<<' '<<i+1<<' '<<"ohhh"<<endl;
    134                 if(b[i]!=share[x][y])swap(a[i],b[i]);
    135                 int c=0;
    136                 while(belong[c]!=3)++c;
    137                 belong[c]=0;
    138                 int id_a_x=-1,id_b_x=-1,id_c_x=-1;
    139                 for(int j=0;j<(int)seq[x].size();++j)
    140                     if(seq[x][j]==a[i])id_a_x=j;
    141                     else if(seq[x][j]==b[i])id_b_x=j;
    142                     else if(seq[x][j]==c)id_c_x=j;
    143                 int id_a_y=-1,id_b_y=-1,id_c_y=-1;
    144                 for(int j=0;j<(int)seq[y].size();++j)
    145                     if(seq[y][j]==a[i])id_a_y=j;
    146                     else if(seq[y][j]==b[i])id_b_y=j;
    147                     else if(seq[y][j]==c)id_c_y=j;
    148                 bool simple_x=id_c_x==(id_b_x+1)%(int)seq[x].size()||(id_c_x+1)%(int)seq[x].size()==id_b_x;
    149                 bool simple_y=id_c_y==(id_b_y+1)%(int)seq[y].size()||(id_c_y+1)%(int)seq[y].size()==id_b_y;
    150                 if(!simple_x)
    151                     if((id_a_x+1)%(int)seq[x].size()==id_b_x)
    152                         for(int j=(id_b_x+1)% seq[x].size();j!=id_c_x;j=(j+1)% seq[x].size())belong[seq[x][j]]=0;
    153                     else for(int j=(id_c_x+1)% seq[x].size();j!=id_b_x;j=(j+1)% seq[x].size())belong[seq[x][j]]=0;
    154                 if(!simple_y)
    155                     if((id_a_y+1)%(int)seq[y].size()==id_b_y)
    156                         for(int j=(id_b_y+1)% seq[y].size();j!=id_c_y;j=(j+1)% seq[y].size())belong[seq[y][j]]=0;
    157                     else for(int j=(id_c_y+1)% seq[y].size();j!=id_b_y;j=(j+1)% seq[y].size())belong[seq[y][j]]=0;
    158                 dsu p(n+4);
    159                 for(int j=i;j<n;++j){
    160                     if(a[j]<i+4&&a[j]!=b[i]){if(belong[a[j]])p.mask[j+4]|=1<<(belong[a[j]]-1);}
    161                     else p.unite(a[j],j+4);
    162                     if(b[j]<i+4&&b[j]!=b[i]){if(belong[b[j]])p.mask[j+4]|=1<<(belong[b[j]]-1);}
    163                     else p.unite(b[j],j+4);
    164                 }
    165                 int mask=p.mask[p.find(b[i])];
    166                 if(mask==3)return 0;
    167                 else if(mask==1)put(i,y);
    168                 else if(mask==2)put(i,x);
    169                 else if(simple_x)put(i,x);
    170                 else put(i,y);
    171             }
    172         }return 1;
    173     };
    174     int l=0,r=n;
    175     while(l<r){
    176         int mid=(l+r+1)>>1;
    177         if(check(mid))l=mid; else r=mid-1;
    178     }
    179     cout<<l<<"
    ";
    180 }}
    View Code
  • 相关阅读:
    【原】React操作表单
    【原】使用webpack打包的后,公共请求路径的配置问题
    【原】React中,map出来的元素添加事件无法使用
    codeforces 1288C. Two Arrays(dp)
    Educational Codeforces Round 80 A-E简要题解
    HDU 2586 ( LCA/tarjan算法模板)
    POJ 1330(LCA/倍增法模板)
    POJ 3368 (ST表)
    POJ 3264 Balanced Lineup(ST模板)
    codeforces 1285E. Delete a Segment
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/13139867.html
Copyright © 2011-2022 走看看