zoukankan      html  css  js  c++  java
  • [考试反思]0115省选模拟8:等待

    不好。但凑和。

    再也不相信对拍了(然而肯定还是要写的)

    T1又是一个根号算法(当然可以更优),没想到,写了一个剪枝暴力,本来从复杂度上来说应该有80分,但是因为没有发现

    「加0不算对一个数进行修改」

    一个细节没注意,挂了45分。

    还写对拍了,但是暴力也没有注意这个细节,于是二者愉快的拍上了。。。

    T3的话写了个迷之网络流,感觉不太对于是愉快的写了一个状压。

    话说这辈子第一次靠自己不抄代码把$tarjan$写对,开心。(我为啥没联赛退役?因为它没考啊)

    又愉快的拍上了二十万组。于是自信的交了网络流。

    结果网络流20分,状压50分。。。

    就这些弱智玩意送了小一百分。。。能混到这个rank就靠一个T2

    然而T2是我三道题里花时间最少的,也没写对拍,反而得分最多。。。

    运气好,爱用STL,在别人开数组的地方开了一个$unoredred map$。数据微锅的情况下没有$RE$。靠非实力因素多拿了$13$分。

    所以其实rank应该再掉两个。。。

    考得还是挺烂的,但是这次除了没认真注意细节以外貌似是尽力了。。。

    所以我也做不出什么评价。只能继续加油吧。。。

    T1:序列

    题意:维护序列支持区间加,区间取$max$,询问单点值及从开始到现在为止的变化次数。$n,mle 100000$

    内存限制$32MB$。时间限制$1000ms$

    线段树,假装小清新,维护最大值与最小值并注意+0不算改变后可以拿到80分。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 400002
     4 #define ll long long
     5 #define lc p<<1
     6 #define rc p<<1|1
     7 #define md (cl+cr>>1)
     8 ll lz[S],mn[S],mx[S];int n,a[S],m,tms[S];char s[9];
     9 void up(int p){mn[p]=min(mn[lc],mn[rc]);mx[p]=max(mx[lc],mx[rc]);}
    10 void build(int p=1,int cl=1,int cr=n){
    11     if(cl==cr){mn[p]=mx[p]=a[cl];return;}
    12     build(lc,cl,md);build(rc,md+1,cr);up(p);
    13 }
    14 void down(int p){
    15     if(tms[p])tms[lc]+=tms[p],tms[rc]+=tms[p],tms[p]=0;
    16     if(mn[p]==mx[p])mn[lc]=mn[rc]=mx[lc]=mx[rc]=mn[p],lz[p]=0;
    17     else if(lz[p])mn[lc]+=lz[p],mn[rc]+=lz[p],mx[lc]+=lz[p],mx[rc]+=lz[p],lz[lc]+=lz[p],lz[rc]+=lz[p],lz[p]=0;
    18 }
    19 void Max(int l,int r,int w,int p=1,int cl=1,int cr=n){
    20     if(w<=mn[p])return;
    21     if(l<=cl&&cr<=r&&w>mx[p]){tms[p]++;lz[p]=0;mn[p]=mx[p]=w;return;}
    22     down(p);
    23     if(l<=md)Max(l,r,w,lc,cl,md);
    24     if(r>md)Max(l,r,w,rc,md+1,cr);
    25     up(p);
    26 }
    27 void add(int l,int r,int v,int p=1,int cl=1,int cr=n){
    28     if(v==0)return;
    29     if(l<=cl&&cr<=r){
    30         if(mn[p]==mx[p])mn[p]+=v,mx[p]+=v,lz[p]=0;
    31         else lz[p]+=v,mn[p]+=v,mx[p]+=v;
    32         tms[p]++;return;
    33     }
    34     down(p);
    35     if(l<=md)add(l,r,v,lc,cl,md);
    36     if(r>md)add(l,r,v,rc,md+1,cr);
    37     up(p);
    38 }
    39 int ask(int x,int p=1,int cl=1,int cr=n){
    40     if(cl==cr)return p;
    41     down(p);
    42     return x<=md?ask(x,lc,cl,md):ask(x,rc,md+1,cr);
    43 }
    44 int main(){//freopen("1.in","r",stdin);freopen("1.out","w",stdout);
    45     scanf("%d",&n);
    46     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    47     build();
    48     scanf("%d",&m);while(m-->0){
    49         scanf("%s",s);int a,b,c;
    50         if(s[0]=='A')scanf("%d%d%d",&a,&b,&c),add(a,b,c);
    51         if(s[0]=='M')scanf("%d%d%d",&a,&b,&c),Max(a,b,c);
    52         if(s[0]=='Q')scanf("%d",&a),a=ask(a),printf("%lld %d
    ",mn[a],tms[a]);
    53     }
    54 }
    View Code

    正解很多,能看懂的就一个分块。块内部排序,维护加法标记和「已经进行过的取max中的最大值」两个标记。

    有序之后,变化次数的累加可以差分,而且如果整个块都被操作的话单调性不变。

    然后T的还不如线段树。把块长开成36之后它AC了???36是个什么块啊?????

    理论复杂度$O(nsqrt{n} log n)$。然而我常数写太丑了。。。卡过去的

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 400002
     4 #define ll long long
     5 ll lz[S],mx[S];int bc,n,m,tms[S],cl[S],cr[S],bl[S],B,lzt[S],pt[S];char s[9];
     6 struct data{long long v;int p;}da[S];
     7 bool cv(data x,data y){return x.v<y.v;}
     8 bool cp(data x,data y){return x.p<y.p;}
     9 void down(int x){
    10     for(int i=cr[x]-1;i>=cl[x];--i)lzt[i]+=lzt[i+1];
    11     for(int i=cl[x];i<=cr[x];++i)tms[da[i].p]+=lzt[i],lzt[i]=0;
    12     for(int i=cl[x];i<=cr[x];++i)da[i].v+=lz[x];
    13     for(int i=cl[x];i<=cr[x];++i)if(da[i].v<mx[x])da[i].v=mx[x];
    14     lz[x]=0;mx[x]=-123456789012345;pt[x]=cl[x];
    15     sort(da+cl[x],da+cr[x]+1,cp);
    16 }
    17 void up(int x){sort(da+cl[x],da+cr[x]+1,cv);}
    18 int main(){//freopen("1.in","r",stdin);freopen("1.out","w",stdout);
    19     scanf("%d",&n);
    20     for(int i=1;i<=n;++i)scanf("%lld",&da[i].v),da[i].p=i;
    21     B=36;bc=n/B;
    22     for(int i=1;i<=bc;++i)cl[i]=i*B-B+1,cr[i]=i*B;
    23     if(cr[bc]!=n)cr[++bc]=n,cl[bc]=cr[bc-1]+1;
    24     for(int i=1;i<=bc;++i)for(int j=cl[i];j<=cr[i];++j)bl[j]=i;
    25     for(int i=1;i<=bc;++i)up(i),mx[i]=-123456789012345,pt[i]=cl[i];
    26     scanf("%d",&m);while(m-->0){
    27         scanf("%s",s);int a,b,c;
    28         if(s[0]=='A'){
    29             scanf("%d%d%d",&a,&b,&c);
    30             if(c==0)continue;
    31             if(bl[a]==bl[b]){down(bl[a]);for(int i=a;i<=b;++i)da[i].v+=c,tms[i]++;up(bl[a]);}
    32             else{
    33                 down(bl[a]);for(int i=a;i<=cr[bl[a]];++i)da[i].v+=c,tms[i]++;up(bl[a]);
    34                 down(bl[b]);for(int i=cl[bl[b]];i<=b;++i)da[i].v+=c,tms[i]++;up(bl[b]);
    35                 for(int i=bl[a]+1;i<bl[b];++i)lz[i]+=c,mx[i]+=c,lzt[cr[i]]++;
    36             }
    37         }
    38         if(s[0]=='M'){
    39             scanf("%d%d%d",&a,&b,&c);
    40             if(bl[a]==bl[b]){down(bl[a]);for(int i=a;i<=b;++i)if(da[i].v<c)da[i].v=c,tms[i]++;up(bl[a]);}
    41             else{
    42                 down(bl[a]);for(int i=a;i<=cr[bl[a]];++i)if(da[i].v<c)da[i].v=c,tms[i]++;up(bl[a]);
    43                 down(bl[b]);for(int i=cl[bl[b]];i<=b;++i)if(da[i].v<c)da[i].v=c,tms[i]++;up(bl[b]);
    44                 for(int i=bl[a]+1;i<bl[b];++i){
    45                     if(c<=mx[i])continue;
    46                     while(pt[i]<cr[i]&&lz[i]+da[pt[i]+1].v<c)pt[i]++;
    47                     if(lz[i]+da[pt[i]].v>=c)continue;
    48                     lzt[pt[i]]++;mx[i]=c;
    49                 }
    50             }
    51         }
    52         if(s[0]=='Q')scanf("%d",&a),down(bl[a]),printf("%lld %d
    ",da[a].v,tms[a]),up(bl[a]);
    53     }
    54 }
    View Code

    T2:旅行计划

    题意:无向图多次询问两点之间在模意义下的最短路(询问间模数可能不同)$n,m,q le 10^5$

    子任务:$k$为奇数/$k=2,w=1$

    其实这两档部分分给的挺好的,但是想到正解仍然不容易。

    k为奇数时你可以在同一条边来回走直到刷出你想要的数,所以只要联通答案就是$0$

    对于后者,奇偶染色判奇环,如果联通块内存在奇环一定可以刷出想要的余数,否则就看两个点颜色是否相同。

    对于其它子任务,因为要取模和环的问题所以考场上我想到了要gcd,然后就想不下去了。

    事实上我们预处理把每个联通块里的边都除以边权的gcd再奇偶染色。

    询问时,如果模数中2的指数少于边的gcd中的2的指数,那么余数一定是0。

    否则如果k是奇数也可以刷出想要的数。

    否则如果有奇环也一定能刷出来。

    再否则如果染色相同那么也就不用刷了最短路模完就是0了。

    再否则,我们也可以通过刷边的方法,将答案最小化为$gcd(k,gcd(edge))$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 200005
     4 int n,m,q,fir[S],l[S],to[S],v[S],bl[S],co[S],y[S],tim,g,ans,k,ec,eg[S];
     5 void link(int a,int b,int c){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;v[ec]=c;}
     6 void paint(int p,int c){
     7     bl[p]=tim;co[p]=c;
     8     for(int i=fir[p];i;i=l[i])if(!co[to[i]])paint(to[i],(co[p]+v[i]&1)+2);
     9         else if((co[p]+v[i]&1)+2!=co[to[i]])y[tim]=1;
    10 }
    11 int gcd(int a,int b){return b?gcd(b,a%b):a;}
    12 int main(){
    13     scanf("%d%d%d",&n,&m,&q);
    14     for(int i=1,a,b,c;i<=m;++i)scanf("%d%d%d",&a,&b,&c),link(a,b,c),link(b,a,c);
    15     for(int i=1;i<=n;++i)if(!co[i])tim++,paint(i,2);
    16     for(int i=1;i<=n;++i)for(int j=fir[i];j;j=l[j])eg[bl[i]]=gcd(eg[bl[i]],v[j]);
    17     for(int i=1;i<=tim;++i)y[i]=0;
    18     for(int i=1;i<=n;++i)for(int j=fir[i];j;j=l[j])v[j]/=eg[bl[i]];
    19     for(int i=1;i<=n;++i)co[i]=0;tim=0;
    20     for(int i=1;i<=n;++i)if(!co[i])tim++,paint(i,2);
    21     while(q-->0){
    22         int x;scanf("%d%d%d",&x,&g,&k);
    23         if(bl[x]!=bl[g])puts("NIE");
    24         else printf("%d
    ",eg[bl[x]]/gcd(k,eg[bl[x]])%2==0||k&1||y[bl[x]]||co[x]==co[g]?0:gcd(k,eg[bl[x]]));
    25     }
    26 }
    View Code

    T3:Hack

    题意:有向联通图,选定边集使所有1到n的路径均经过边集中的边合计恰好一次,最小化边权和。$nle100,m le 2500$

    模型很像最小割。但是最小割并没有保证恰好经过一次。

    经过多于一次的方案就是走某些路径由最小割后$T$点集走回了$S$点集。

    于是我们把反向边开成$inf$就好了。这样就保证了即使它可以往回走的路径也被割断。

    然而没必要$tarjan$缩点。直接按照含义跑,最后最小割是0表示不联通,无解。最小割$inf$表示都至少经过两次,也无解。

    判掉之后你的网络流图上反向边$inf$成环所以你一定不割环上边所以是对的。$miku$大神实测可以$AC$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 1234567
     4 int fir[S],l[S],to[S],ec,v[S],dfn[S],low[S],tim,in[S],s[S],tp,bl[S],scc,n,m;
     5 void link(int a,int b,int w){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;v[ec]=w;}
     6 void tarjan(int p){
     7     dfn[p]=low[p]=++tim;s[++tp]=p;in[p]=1;
     8     for(int i=fir[p];i;i=l[i])if(!dfn[to[i]])tarjan(to[i]),low[p]=min(low[p],low[to[i]]);
     9         else if(in[to[i]])low[p]=min(low[p],dfn[to[i]]);
    10     if(dfn[p]==low[p]){++scc;while(in[p])in[s[tp]]=0,bl[s[tp]]=scc,tp--;}
    11 }
    12 int Fir[S],L[S],To[S],q[S],Ec=1,al[S],d[S];long long ans,V[S];
    13 void Link(int a,int b,int w){
    14     L[++Ec]=Fir[a];Fir[a]=Ec;To[Ec]=b;V[Ec]=w;
    15     L[++Ec]=Fir[b];Fir[b]=Ec;To[Ec]=a;V[Ec]=123456789012345;
    16 }
    17 bool SPFA(){
    18     for(int i=1;i<=scc;++i)d[i]=123456789;d[bl[1]]=0;q[1]=bl[1];
    19     for(int h=1,t=1;h<=t;++h)for(int i=Fir[q[h]];i;i=L[i])if(V[i]&&d[q[h]]+1<d[To[i]])
    20         d[q[++t]=To[i]]=d[q[h]]+1;
    21     return d[bl[n]]!=123456789;
    22 }
    23 long long dinic(int p,long long flow){//cout<<p<<' '<<flow<<endl;
    24     long long r=flow;
    25     if(p==bl[n])return flow;
    26     for(int i=Fir[p];i&&r;i=L[i])if(d[To[i]]==d[p]+1&&V[i]){
    27         long long x=dinic(To[i],min(r,V[i]));
    28         if(!x)d[To[i]]=-1;
    29         V[i]-=x;V[i^1]+=x;r-=x;
    30     }return flow-r;
    31 }
    32 int main(){//freopen("3.in","r",stdin);freopen("3.out","w",stdout);
    33     scanf("%d%d",&n,&m);
    34     for(int i=1,a,b,w;i<=m;++i)scanf("%d%d%d",&a,&b,&w),link(a+1,b+1,w);
    35     tarjan(1);
    36     if(bl[1]==bl[n]||!bl[n])return puts("-1"),0;
    37     for(int i=1;i<=n;++i)for(int j=fir[i];j;j=l[j])if(bl[i]&&bl[to[j]]&&bl[to[j]]!=bl[i])Link(bl[i],bl[to[j]],v[j]);
    38     while(SPFA())ans+=dinic(bl[1],123456789012345);
    39     printf("%lld
    ",ans);
    40 }
    View Code

    .

  • 相关阅读:
    c#自动更新+安装程序的制作
    VS2013项目受源代码管理向源代码管理注册此项目时出错
    WinDbg配置和使用基础
    InstallShield Limited Edition for Visual Studio 2013 图文教程(教你如何打包.NET程序)
    PowerDesigner 如何生成数据库更新脚本
    用户故事(User Story)
    Troubleshooting Record and Playback issues in Coded UI Test
    Coded UI
    compare two oracle database schemas
    How to: Use Schema Compare to Compare Different Database Definitions
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12198374.html
Copyright © 2011-2022 走看看