2021.8.14考试总结[NOIP模拟39]

T1 打地鼠


全场就俩人没切,还有一个是忘关$freopen$了。

$code:$

 1 #include<bits/stdc++.h>
 2 #define rin register signed
 3 using namespace std;
 4 const int NN=2e3+5;
 5 int n,k,pre[NN][NN],ans;
 6 char ch[NN];
 7 inline int read(){
 8     int x=0,f=1; char ch=getchar();
 9     while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
10     while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
11     return x*f;
12 }
13 inline void write(int x,char sp){
14     char ch[25]; int len=0;
15     if(x<0){ putchar('-'); x=~x+1; }
16     do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
17     for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
18 }
19 signed main(){
20     n=read(); k=read();
21     for(rin i=1;i<=n;i++){
22         scanf("%s",ch+1);
23         for(rin j=1;j<=n;j++)
24             pre[i][j]=pre[i][j-1]+(ch[j]=='1');
25         for(rin j=1;j<=n;j++) pre[i][j]+=pre[i-1][j];
26     }
27     for(int i=0;i<=n-k;i++)
28         for(int j=0;j<=n-k;j++)
29             ans=max(ans,pre[i+k][j+k]+pre[i][j]-pre[i][j+k]-pre[i+k][j]);
30     write(ans,'\n');
31     return 0;
32 }
T1

T2 竞赛图


竞赛图缩点后会形成一条链,因此对一个不强联通的子图$S$,必然存在且只有一个强联通的子图$T$,满足$S-T$中点的边都是$S \to T$的。

考虑通过这个性质用强联通子图更新不强联通子图。预处理出每个子集所有点出边的交集即可。

$code:$

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int NN=24;
 4 int t,n,to[1<<NN],S,ans;
 5 bool is[1<<NN];
 6 inline int read(){
 7     int x=0,f=1; char ch=getchar();
 8     while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
 9     while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
10     return x*f;
11 }
12 inline void write(int x,char sp){
13     char ch[20]; int len=0;
14     if(x<0){ putchar('-'); x=~x+1; }
15     do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
16     for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
17 }
18 signed main(){
19     t=read();
20     while(t--){
21         memset(to,0,sizeof(to)); memset(is,1,sizeof(is));
22         n=read(); to[0]=S=(1<<n)-1; ans=0;
23         for(int i=0;i<n;i++) for(int j=0;j<n;j++)
24             if(read()) to[1<<i]|=1<<j;
25         for(int i=1;i<=S;i++) to[i]=to[i^(i&(-i))]&to[i&(-i)];
26         for(int i=1;i<=S;i++)
27             if(is[i])
28                 for(int j=to[i];j;j=(j-1)&to[i]) is[i|j]=0;
29         for(int i=0;i<=S;i++) if(is[i]) ++ans;
30         write(ans,'\n');
31     }
32     return 0;
33 }
T2

T3 糖果


神仙$DP$,没改出来,钴了。

T4 树


$\textit{NOI D1T1}$原题,把黑白边反过来了。

树剖,边权下放,每次修改将路径上点打上时间戳,发现黑边数量其实就是相邻两边时间戳不同的边对数。

一开始建树时要保证所有点的时间戳不同。

$code:$

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int NN=3e5+5;
  4 int q,n,idx,to[NN<<1],nex[NN<<1],head[NN],tp,x,y;
  5 int siz[NN],son[NN],top[NN],dfn[NN],fa[NN],dep[NN],cnt,tim;
  6 inline int read(){
  7     int x=0,f=1; char ch=getchar();
  8     while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
  9     while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
 10     return x*f;
 11 }
 12 inline void write(int x,char sp){
 13     char ch[20]; int len=0;
 14     if(x<0){ putchar('-'); x=~x+1; }
 15     do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
 16     for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
 17 }
 18 inline void add(int a,int b){
 19     to[++idx]=b; nex[idx]=head[a]; head[a]=idx;
 20     to[++idx]=a; nex[idx]=head[b]; head[b]=idx;
 21 }
 22 void dfs1(int s,int f){
 23     siz[s]=1; fa[s]=f; dep[s]=dep[f]+1;
 24     for(int i=head[s];i;i=nex[i]){
 25         int v=to[i];
 26         if(v==f) continue;
 27         dfs1(v,s);
 28         siz[s]+=siz[v];
 29         if(siz[v]>siz[son[s]]) son[s]=v;
 30     }
 31 }
 32 void dfs2(int s,int t){
 33     dfn[s]=++cnt; top[s]=t;
 34     if(!son[s]) return;
 35     dfs2(son[s],t);
 36     for(int i=head[s];i;i=nex[i]){
 37         int v=to[i];
 38         if(v!=fa[s]&&v!=son[s]) dfs2(v,v);
 39     }
 40 }
 41 struct segment_tree{
 42     #define ld rt<<1
 43     #define rd (rt<<1)|1
 44     int sum[NN<<2],lc[NN<<2],rc[NN<<2],laz[NN<<2];
 45     void pushup(int rt){
 46         sum[rt]=sum[ld]+sum[rd]+(rc[ld]!=lc[rd]);
 47         lc[rt]=lc[ld]; rc[rt]=rc[rd];
 48     }
 49     void pushdown(int rt){
 50         if(!laz[rt]) return;
 51         laz[ld]=laz[rt]; laz[rd]=laz[rt];
 52         sum[ld]=sum[rd]=0;
 53         lc[ld]=lc[rd]=rc[ld]=rc[rd]=laz[rt];
 54         laz[rt]=0;
 55     }
 56     void build(int rt,int l,int r){
 57         if(l==r){ lc[rt]=rc[rt]=l; return; }
 58         int mid=l+r>>1;
 59         build(ld,l,mid);
 60         build(rd,mid+1,r);
 61         pushup(rt);
 62     }
 63     void modify(int rt,int l,int r,int opl,int opr,int v){
 64         if(l>=opl&&r<=opr){
 65             sum[rt]=0;
 66             lc[rt]=rc[rt]=laz[rt]=v;
 67             return;
 68         }
 69         pushdown(rt);
 70         int mid=l+r>>1;
 71         if(opl<=mid) modify(ld,l,mid,opl,opr,v);
 72         if(opr>mid) modify(rd,mid+1,r,opl,opr,v);
 73         pushup(rt);
 74     }
 75     int query(int rt,int l,int r,int opl,int opr){
 76         if(l>=opl&&r<=opr) return sum[rt];
 77         pushdown(rt);
 78         int mid=l+r>>1;
 79         if(opr<=mid) return query(ld,l,mid,opl,opr);
 80         else if(opl>mid) return query(rd,mid+1,r,opl,opr);
 81         else return query(ld,l,mid,opl,mid)+query(rd,mid+1,r,mid+1,opr)+(lc[rd]!=rc[ld]);
 82     }
 83     int look(int rt,int l,int r,int pos){
 84         if(l==r) return lc[rt];
 85         pushdown(rt);
 86         int mid=l+r>>1;
 87         if(pos<=mid) return look(ld,l,mid,pos);
 88         else return look(rd,mid+1,r,pos);
 89     }
 90 }s;
 91 void UPD(int x,int y){
 92     int fx=top[x],fy=top[y]; ++tim;
 93     while(fx!=fy)
 94         if(dep[fx]>dep[fy]){
 95             s.modify(1,1,n,dfn[fx],dfn[x],tim);
 96             x=fa[fx]; fx=top[x];
 97         }
 98         else{
 99             s.modify(1,1,n,dfn[fy],dfn[y],tim);
100             y=fa[fy]; fy=top[y];
101         }
102     if(dep[x]>dep[y]) s.modify(1,1,n,dfn[y],dfn[x],tim);
103     else s.modify(1,1,n,dfn[x],dfn[y],tim);
104 }
105 int ANS(int x,int y){
106     int ans=0,fx=top[x],fy=top[y];
107     while(fx!=fy)
108         if(dep[fx]>dep[fy]){
109             ans+=s.query(1,1,n,dfn[fx],dfn[x]);
110             ans+=(s.look(1,1,n,dfn[fx])!=s.look(1,1,n,dfn[fa[fx]]));
111             x=fa[fx]; fx=top[x];
112         }
113         else{
114             ans+=s.query(1,1,n,dfn[fy],dfn[y]);
115             ans+=(s.look(1,1,n,dfn[fy])!=s.look(1,1,n,dfn[fa[fy]]));
116             y=fa[fy]; fy=top[y];
117         }
118     if(dep[x]<dep[y]) ans+=s.query(1,1,n,dfn[x],dfn[y]);
119     else ans+=s.query(1,1,n,dfn[y],dfn[x]);
120     return ans;
121 }
122 signed main(){
123     tim=n=read();
124     for(int i=1;i<n;i++) add(read(),read());
125     dfs1(1,0); dfs2(1,1);
126     s.build(1,1,n);
127     q=read();
128     while(q--){
129         tp=read(); x=read(); y=read();
130         if(tp==1) UPD(x,y);
131         if(tp==2) write(ANS(x,y),'\n');
132     }
133     return 0;
134 }
T4

 

posted @ 2021-08-15 06:16  keen_z  阅读(42)  评论(0编辑  收藏  举报