zoukankan      html  css  js  c++  java
  • NOI2015

    T1 4195: [Noi2015]程序自动分析

    喵喵喵?这题普及组就能切了吧?直接离散后并查集合并相等关系,枚举每个不等关系判断即可.

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    13 const int N=1000007;
    14 typedef long long LL; 
    15 typedef double db;
    16 using namespace std;
    17 int T,n,fa[N],ls[N],sz;
    18 
    19 template<typename T> void read(T &x) {
    20     char ch=getchar(); x=0; T f=1;
    21     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    22     if(ch=='-') f=-1,ch=getchar();
    23     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    24 }
    25 
    26 struct node {
    27     int i,j,e;
    28     node(){}
    29     node(int i,int j,int e):i(i),j(j),e(e){}
    30 }p[N];
    31 
    32 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
    33 int lik(int x,int y) {
    34     if(find(x)!=find(y)) fa[find(x)]=find(y);
    35 }
    36 
    37 int main() {
    38 #ifdef DEBUG
    39     freopen(".in","r",stdin);
    40     freopen(".out","w",stdout);
    41 #endif
    42     read(T);
    43     while(T--) {
    44         read(n); sz=0;
    45         For(t,1,n) { 
    46             int i,j,e;
    47             read(i); read(j); read(e);
    48             ls[++sz]=i; ls[++sz]=j;
    49             p[t]=node(i,j,e);
    50         }
    51         sort(ls+1,ls+sz+1);
    52         int tpsz=unique(ls+1,ls+sz+1)-(ls+1);
    53         sz=tpsz;
    54         For(i,1,sz) fa[i]=i;
    55         For(i,1,n) {
    56             p[i].i=lower_bound(ls+1,ls+sz+1,p[i].i)-ls;
    57             p[i].j=lower_bound(ls+1,ls+sz+1,p[i].j)-ls;
    58             if(p[i].e) lik(p[i].i,p[i].j);
    59         }
    60         int fl=1;
    61         For(i,1,n) if(!p[i].e) {
    62             int x=p[i].i,y=p[i].j;
    63             if(find(x)==find(y)) {
    64                 fl=0;
    65                 break;
    66             }
    67         }
    68         if(!fl) puts("NO");
    69         else puts("YES");
    70     }
    71     return 0;
    72 }
    73 /*
    74 2
    75 2
    76 1 2 1
    77 1 2 0
    78 2
    79 1 2 1
    80 2 1 1
    81 */
    View Code

     

    T2 4196: [Noi2015]软件包管理器

    ??? 裸的树剖,不知道出题人怎么想的.

      1 //Achen
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<cmath>
     10 #include<set>
     11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     13 const int N=100007;
     14 typedef long long LL; 
     15 typedef double db;
     16 using namespace std;
     17 int n,q;
     18 char o[20];
     19 
     20 template<typename T> void read(T &x) {
     21     char ch=getchar(); x=0; T f=1;
     22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     23     if(ch=='-') f=-1,ch=getchar();
     24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     25 }
     26 
     27 int sg[N<<2],lz[N<<2];
     28 #define lc x<<1
     29 #define rc ((x<<1)|1)
     30 #define mid ((l+r)>>1)
     31 void add_it(int x,int len,int v) {
     32     if(v==1) sg[x]=len; else sg[x]=0; lz[x]=v; 
     33 }
     34 
     35 void down(int x,int l_len,int r_len) {
     36     if(!lz[x]) return;
     37     if(l_len) add_it(lc,l_len,lz[x]);
     38     if(r_len) add_it(rc,r_len,lz[x]);
     39     lz[x]=0;
     40 }
     41 
     42 void update(int x,int l,int r,int ql,int qr,int v) {
     43     if(l>=ql&&r<=qr) {
     44         add_it(x,r-l+1,v); return;
     45     }
     46     down(x,mid-l+1,r-mid);
     47     if(ql<=mid) update(lc,l,mid,ql,qr,v);
     48     if(qr>mid) update(rc,mid+1,r,ql,qr,v);
     49     sg[x]=sg[lc]+sg[rc];
     50 }
     51 
     52 int qry(int x,int l,int r,int ql,int qr) {
     53     if(l>=ql&&r<=qr) return sg[x];
     54     down(x,mid-l+1,r-mid);
     55     if(qr<=mid) return qry(lc,l,mid,ql,qr);
     56     if(ql>mid) return qry(rc,mid+1,r,ql,qr);
     57     return qry(lc,l,mid,ql,qr)+qry(rc,mid+1,r,ql,qr);
     58 }
     59 
     60 int ecnt,fir[N],nxt[N],to[N];
     61 void add(int u,int v) {
     62     nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
     63 }
     64 
     65 int sz[N],R[N],f[N];
     66 void dfs(int x,int fa) {
     67     f[x]=fa; sz[x]=1; R[x]=R[fa]+1;
     68     for(int i=fir[x];i;i=nxt[i]) { 
     69         dfs(to[i],x);
     70         sz[x]+=sz[to[i]];
     71     }
     72 }
     73 
     74 int top[N],dfn[N],low[N],tid[N],dfs_clock;
     75 void DFS(int x,int Top) {
     76     top[x]=Top;
     77     dfn[x]=++dfs_clock;
     78     tid[dfn[x]]=x;
     79     int mxson=0;
     80     for(int i=fir[x];i;i=nxt[i]) if(!mxson||sz[mxson]<sz[to[i]]) mxson=to[i];
     81     if(mxson) DFS(mxson,Top);
     82     for(int i=fir[x];i;i=nxt[i]) if(to[i]!=mxson) DFS(to[i],to[i]);
     83     low[x]=dfs_clock;
     84 }
     85 
     86 int schange(int x,int y,int v) {
     87     while(top[x]!=top[y]) {
     88         if(R[top[x]]<R[top[y]]) swap(x,y);
     89         update(1,1,n,dfn[top[x]],dfn[x],v);
     90         x=f[top[x]];
     91     }
     92     if(dfn[x]>dfn[y]) swap(x,y);
     93     update(1,1,n,dfn[x],dfn[y],v);
     94 }
     95 
     96 int sqry(int x,int y) {
     97     int rs=0;
     98     while(top[x]!=top[y]) {
     99         if(R[top[x]]<R[top[y]]) swap(x,y);
    100         rs+=qry(1,1,n,dfn[top[x]],dfn[x]);
    101         x=f[top[x]];
    102     }
    103     if(dfn[x]>dfn[y]) swap(x,y);
    104     rs+=qry(1,1,n,dfn[x],dfn[y]);
    105     return rs;
    106 }
    107 
    108 int main() {
    109 #ifdef DEBUG
    110     freopen(".in","r",stdin);
    111     freopen(".out","w",stdout);
    112 #endif
    113     read(n);
    114     For(i,2,n) {
    115         int fa; read(fa); 
    116         fa++; add(fa,i);
    117     }
    118     dfs(1,0);
    119     DFS(1,1);
    120     update(1,1,n,1,n,1);
    121     read(q);
    122     For(ti,1,q) {
    123         int x;
    124         scanf("%s",o);
    125         read(x); x++;
    126         if(o[0]=='i') {
    127             printf("%d
    ",sqry(1,x));
    128             schange(1,x,-1);
    129         }
    130         else {
    131             printf("%d
    ",sz[x]-qry(1,1,n,dfn[x],low[x]));
    132             update(1,1,n,dfn[x],low[x],1);
    133         }
    134     }
    135     return 0;
    136 }
    View Code

     

    T3 4197: [Noi2015]寿司晚宴

    容易想到状压dp,小于sqrtn的素因子只有8个,每个数大于sqrtn的素因子仅1个,按这个素因子把数分成不相干的若干类.每一类只能一个人选.

    然后就不知道怎么做了.

    可能从30分暴力开始想容易想到一点.

    30分数据n<=30,那么状压所有素因子,

    f[i][j]表示第1个人选了i这些因子,第2个人选了j这些因子的方案数.

    n<=500时

    对于仅含有小于sqrtn的素因子的数可以和30分一样状压dp.

    对于含有大于sqrtn的素因子的数,相互直接互不影响,那么分成若干组分别dp就好了.

    每一组的dp中,g[0/1][i][j]表示这一组由第0/1个人选的方案数.

    每一组的初值g[0][i][j]=g[1][i][j]=f[i][j]

    最后答案f[i][j]=g[0][i][j]+g[1][i][j]-f[i][j](减去这一组两个人都啥都没选)

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    13 const int N=259;
    14 typedef long long LL; 
    15 typedef double db;
    16 using namespace std;
    17 int n,mod,p[150],sz,ok[507],allin[507];
    18 LL f[N][N],g[2][N][N],ans;
    19 
    20 template<typename T> void read(T &x) {
    21     char ch=getchar(); x=0; T f=1;
    22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    23     if(ch=='-') f=-1,ch=getchar();
    24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    25 }
    26 
    27 int main() {
    28 #ifdef DEBUG
    29     freopen(".in","r",stdin);
    30     freopen(".out","w",stdout);
    31 #endif
    32     read(n); read(mod);
    33     For(i,2,n) {
    34         int fl=1;
    35         For(j,2,i-1) if(i%j==0) {
    36             fl=0; break;
    37         }
    38         if(fl) {
    39             p[++p[0]]=i;
    40             if(i*i<=n) sz++;
    41         }
    42     }
    43     For(i,2,n) {
    44         int tp=i;
    45         For(j,1,sz) if(tp%p[j]==0) {
    46             ok[i]|=(1<<j-1);
    47             while(tp%p[j]==0) tp/=p[j];
    48         }
    49         if(tp==1) allin[i]=1;
    50     }
    51     f[0][0]=1;
    52     int nn=(1<<sz)-1;
    53     For(x,2,n) if(allin[x]) {
    54         Rep(i,nn,0) Rep(j,nn,0) if(f[i][j]) {
    55             if(!(i&ok[x])) (f[i][j|ok[x]]+=f[i][j])%=mod;
    56             if(!(j&ok[x])) (f[i|ok[x]][j]+=f[i][j])%=mod;
    57         }
    58     }
    59     For(id,sz+1,p[0]) {
    60         For(i,0,nn) For(j,0,nn) g[0][i][j]=g[1][i][j]=f[i][j];
    61         for(int x=p[id];x<=n;x+=p[id]) 
    62             Rep(i,nn,0) Rep(j,nn,0) {
    63                 if(!(i&ok[x])) (g[1][i][j|ok[x]]+=g[1][i][j])%=mod;
    64                 if(!(j&ok[x])) (g[0][i|ok[x]][j]+=g[0][i][j])%=mod;
    65             }
    66         For(i,0,nn) For(j,0,nn) f[i][j]=(g[0][i][j]+g[1][i][j]-f[i][j]+mod)%mod;
    67     }
    68     For(i,0,nn) For(j,0,nn) (ans+=f[i][j])%=mod;
    69     printf("%lld
    ",ans);
    70     return 0;
    71 }
    View Code

     

    T4 4198: [Noi2015]荷马史诗

    感觉是树上贪心乱搞.

    然后得知有一种叫哈夫曼树的奥妙的玩意.

    哈夫曼树:

    一些叶子有权值,一颗树的权证为所有叶子的权值乘以叶子的深度的和,求权值最小的树.一般是二叉的.

    先把所有叶子看成一颗单独的树,每次取出权值最小的两个叶子合并,合并后的权值为两个叶子的权值和.

    到这道题上,就是求一个k叉的哈夫曼树.那么每次取出权值最小的k个树来合并.

    当(n-1)%(k-1)不等于0时,需补上一些权值为0的叶子再做.

    要使得深度最大的叶子最小,每次合并时存在权值相同的树时,规定深度小的树权值为小即可.

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    13 const int N=200007;
    14 typedef long long LL; 
    15 typedef double db;
    16 using namespace std;
    17 LL n,k,w[N],anstot,ansh;
    18 
    19 template<typename T> void read(T &x) {
    20     char ch=getchar(); x=0; T f=1;
    21     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    22     if(ch=='-') f=-1,ch=getchar();
    23     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    24 }
    25 
    26 #define pr pair<LL,LL>
    27 #define fi first
    28 #define se second
    29 pr p[N];
    30 priority_queue<pr,vector<pr>,greater<pr> >que;
    31 void build(int n) {
    32     For(i,1,n) que.push(p[i]);
    33     for(;;) {
    34         pr y; 
    35         LL W=0,H=0;
    36         For(i,1,k) {
    37             pr x=que.top();
    38             W+=x.fi;
    39             H=max(H,x.se+1);
    40             que.pop();
    41         }
    42         y.fi=W; y.se=H;
    43         anstot+=W;
    44         if(que.empty()) {
    45             ansh=y.se;
    46             break;
    47         }
    48         que.push(y);
    49     }
    50 }
    51 
    52 int main() {
    53 #ifdef DEBUG
    54     freopen(".in","r",stdin);
    55     freopen(".out","w",stdout);
    56 #endif
    57     read(n); read(k);
    58     For(i,1,n) read(w[i]);
    59     while((n-1)%(k-1)) n++;
    60     For(i,1,n) { p[i].fi=w[i]; p[i].se=0; }
    61     build(n);
    62     printf("%lld %lld
    ",anstot,ansh);
    63     return 0;
    64 }
    View Code

    T5品酒大会

    传送门

  • 相关阅读:
    C# 扩展方法使用
    C# 程序集安装与卸载
    C#截取当前活动窗体的图片
    DateTime格式
    c# asp.net 多数组索引的解决方法
    关于DataSet中Relations的应用
    datalist 分页
    ASP.NET(C#) Repeater分页的实现
    asp.net 六大对象之Request、Response
    什么是DOM
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8796285.html
Copyright © 2011-2022 走看看