zoukankan      html  css  js  c++  java
  • NOIp2018集训test-9-1(am)

    1、最大值

    可以用FWT水过去,李巨写了FWT结果中途爆int了炸了几十分好像。

    我乱搞了一下把除了大数据有or的搞出来然后90,还是蛮划算的。我yy的做法:

    1、xor 字典树上贪心, 一开始我打了线性基,被自己蠢哭了。

    &和|

    用sum[i]表示i中二进制位为1的位置都是1的且不是i的数是否存在。我乱搞从大到小地把一个一个去掉处理的,FWT也可以处理这个,复杂度是一样的。

    2、&

      答案一定是a中的某个数,枚举a中的每个数a[i]看sum[a[i]]是否存在即可。

    3、|

      枚举a中每个数,从高位到低位贪心看它能|出来的最大数。用一个类似前缀和思想的限制,具体说,到某一位如果a[i]是0,看目前的限制|这一位的1的sum存不存在,存在就把目前的限制|这一位的1。

      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 #include<map>
     12 #define Formylove return 0
     13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     15 const int N=1e5+7;
     16 typedef long long LL;
     17 typedef double db;
     18 using namespace std;
     19 int T,n,c,a[N],mxx,b[30],sum[1048579],cnt[1048579];
     20 
     21 template<typename T>void read(T &x)  {
     22     char ch=getchar(); x=0; T f=1;
     23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     24     if(ch=='-') f=-1,ch=getchar();
     25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     26 }
     27 
     28 int rt,ch[N*25][2],tot;
     29 void insert(int v) {
     30     int x=rt;
     31     For(i,0,20) {
     32         int c=((v&(1<<i))!=0);
     33         if(!ch[x][c]) {
     34             ch[x][c]=++tot;
     35             ch[tot][0]=ch[tot][1]=0;
     36         }
     37         x=ch[x][c];
     38     }
     39 }
     40 
     41 int qry(int v) {
     42     int x=rt,rs=0;
     43     For(i,0,20) {
     44         if(v&(1<<i)) {
     45             if(ch[x][0]) rs+=(1<<i),x=ch[x][0];
     46             else x=ch[x][1];
     47         }
     48         else {
     49             if(ch[x][1]) rs+=(1<<i),x=ch[x][1];
     50             else x=ch[x][0];
     51         }    
     52     }
     53     return rs;
     54 }
     55 
     56 #define ANS
     57 int main() {
     58 #ifdef ANS
     59     freopen("maximum.in","r",stdin);
     60     freopen("maximum.out","w",stdout);
     61 #endif
     62     read(T);
     63     while(T--) {
     64         read(n); read(c);
     65         For(i,1,n) { read(a[i]); if(a[i]>mxx) mxx=a[i]; } 
     66         if(n<=1000) {
     67             int ans=0;
     68             For(i,1,n) For(j,i+1,n) {
     69                 if(c==1) ans=max(ans,(a[i]&a[j]));
     70                 else if(c==2) ans=max(ans,(a[i]^a[j]));
     71                 else ans=max(ans,(a[i]|a[j]));
     72             }
     73             printf("%d
    ",ans);
     74         }
     75         else if(mxx<=1024) {
     76             int ans=0;
     77             For(i,0,1024) cnt[i]=0;
     78             For(i,1,n) cnt[a[i]]++;
     79             For(i,0,1024) if(cnt[i]) {
     80                 if(cnt[i]>=2) {
     81                     if(c==1) ans=max(ans,(i&i));
     82                     else if(c==2) ans=max(ans,(i^i));
     83                     else ans=max(ans,(i|i));
     84                 }
     85                 For(j,i+1,1024) if(cnt[j]) {
     86                     if(c==1) ans=max(ans,(i&j));
     87                     else if(c==2) ans=max(ans,(i^j));
     88                     else ans=max(ans,(i|j));
     89                 }
     90             }
     91             printf("%d
    ",ans);
     92         }
     93         else {
     94             if(c!=2) {
     95                 memset(cnt,0,sizeof(cnt));
     96                 memset(sum,0,sizeof(sum));
     97                 int up=mxx;
     98                  For(i,1,n) {
     99                      cnt[a[i]]++;
    100                     For(j,0,20) if(a[i]&(1<<j)) 
    101                         sum[a[i]^(1<<j)]=1;
    102                 }
    103                 Rep(i,up,0) if(sum[i]) {
    104                     For(j,0,20) if(i&(1<<j)) 
    105                         sum[i^(1<<j)]=1;
    106                 }
    107             } 
    108             if(c==1) { //&
    109                 int ans=0;
    110                  For(i,1,n) if(cnt[a[i]]>=1||sum[a[i]]) {
    111                     if(a[i]>ans) ans=a[i]; 
    112                 }
    113                 printf("%d
    ",ans);
    114             } 
    115             else if(c==2) { //^
    116                 int rs=0;
    117                 ch[rt][0]=ch[rt][1]=0;
    118                 For(i,1,n) insert(a[i]);
    119                 For(i,1,n) rs=max(rs,qry(a[i]));
    120                 printf("%d
    ",rs);
    121             }
    122             else { // |
    123                 int ans=0;
    124                 For(i,1,n) {
    125                     int pr=0;
    126                     Rep(j,20,0) if(!(i&(1<<j))) {
    127                         if(sum[pr|(1<<j)]||cnt[pr|(1<<j)]) pr|=(1<<j);
    128                     }
    129                     ans=max(ans,(a[i]|pr));
    130                 }
    131                 printf("%d
    ",ans);
    132             }
    133         }
    134     }
    135     Formylove;
    136 }
    View Code

    2、独木桥

    之前考过的题啊。二分套二分。

    老张给的大数据有毒,大数据给错了,害我调了1个小时。。。

     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 #include<map>
    12 #define Formylove return 0
    13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    15 const int N=2e5+7;
    16 typedef long long LL;
    17 typedef double db;
    18 using namespace std;
    19 int n,m,d;
    20 int px[N],rak[N],p[N],lp[N],rp[N],mi,mx;
    21 
    22 template<typename T>void read(T &x)  {
    23     char ch=getchar(); x=0; T f=1;
    24     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    25     if(ch=='-') f=-1,ch=getchar();
    26     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    27 }
    28 
    29 int find(int ti,int pos) {
    30     int rs=0;
    31     int l=1,r=lp[0],tp=-1;
    32     while(l<=r) {
    33         int mid=((l+r)>>1);
    34         if(lp[mid]-ti<=pos) tp=mid,l=mid+1; 
    35         else r=mid-1;
    36     }
    37     if(tp!=-1) rs+=tp;
    38     l=1,r=rp[0],tp=-1;
    39     while(l<=r) {
    40         int mid=((l+r)>>1);
    41         if(rp[mid]+ti<=pos) tp=mid,l=mid+1;
    42         else r=mid-1;
    43     }
    44     if(tp!=-1) rs+=tp;
    45     return rs;
    46 }
    47 
    48 #define ANS
    49 int main() {
    50 #ifdef ANS
    51     freopen("bridge.in","r",stdin);
    52     freopen("bridge.out","w",stdout);
    53 #endif
    54     read(n);
    55     For(i,1,n) read(p[i]),px[i]=p[i];
    56     sort(px+1,px+n+1);
    57     For(i,1,n) rak[i]=lower_bound(px+1,px+n+1,p[i])-px; 
    58     For(i,1,n) {
    59         read(d);
    60         if(d) rp[++rp[0]]=p[i];
    61         else lp[++lp[0]]=p[i];
    62         mi=min(mi,p[i]); mx=max(mx,p[i]);
    63     }
    64     sort(rp+1,rp+rp[0]+1);
    65     sort(lp+1,lp+lp[0]+1);
    66     read(m);
    67     For(i,1,m) {
    68         int ti,k;
    69         read(k); k++; read(ti);
    70         k=rak[k];
    71         int l=mi-ti,r=mx+ti,rs=-1;
    72         while(l<=r) {
    73             int mid=(((LL)l+r)/2);
    74             if(find(ti,mid)>=k) rs=mid,r=mid-1;
    75             else l=mid+1;
    76         }
    77         printf("%d
    ",rs);
    78     }
    79     Formylove;
    80 }
    81 /*
    82 5
    83 8 7 8 1 4 
    84 0 1 1 0 1 
    85 5
    86 5 11
    87 */
    View Code

    3、分组

    把s从小到大排序,一个个考虑放进组中,这样可以保证新建组的时候放入的一定是组内最小数,结束一个组的时候放入的一定是组内最大数。

    f[i][j][c]表示前i个数都分进了组,现在还有j个组没有结束,目前的代价是c的方案数。这样就可以过$sum s_i < 1000$的点了。

    算代价的时候是分别在最小的地方-s[i]和在最大的地方+s[i],显然代价单调不减,也就是虽然某个地方可能代价-s[i]但是后面一定会把这个代价加到非负。所以c一维最大只会到k。

    虽然最大只会到k,但是最小可以小到非常小,所以这种算代价的方式不太优秀。利用差分的思想,$s_i-s_j=sum_{k=j}^{k<i}s_{k+1}-s_k$,这样就可以使代价始终为正,把第三维压到k了。

     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 #include<map>
    12 #define Formylove return 0
    13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    15 const int p=1e9+7;
    16 typedef long long LL;
    17 typedef double db;
    18 using namespace std;
    19 int n,k,s[205];
    20 LL f[2][205][1005],cf[205];
    21 
    22 template<typename T>void read(T &x)  {
    23     char ch=getchar(); x=0; T f=1;
    24     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    25     if(ch=='-') f=-1,ch=getchar();
    26     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    27 }
    28 
    29 #define ANS
    30 int main() {
    31 #ifdef ANS
    32     freopen("group.in","r",stdin);
    33     freopen("group.out","w",stdout);
    34 #endif
    35     read(n); read(k);
    36     For(i,1,n) read(s[i]);
    37     sort(s+1,s+n+1);
    38     For(i,1,n) cf[i]=s[i+1]-s[i];
    39     int o=0;
    40     f[o][0][0]=1;
    41     For(i,0,n-1) {
    42         o^=1;
    43         memset(f[o],0,sizeof(f[o]));
    44         For(j,0,i) For(c,0,k) if(f[o^1][j][c]) {
    45             if(c+cf[i]*j<=k) {
    46                 (f[o][j][c+cf[i]*j]+=f[o^1][j][c]*(j+1)%p)%=p;
    47                 if(j) (f[o][j-1][c+cf[i]*j]+=(f[o^1][j][c]*j%p))%=p;
    48                 (f[o][j+1][c+cf[i]*j]+=f[o^1][j][c])%=p;
    49             }
    50         }
    51     }
    52     LL ans=0;
    53     For(i,0,k) 
    54         (ans+=f[o][0][i])%=p;
    55     printf("%lld
    ",ans);
    56     Formylove;
    57 }
    View Code
  • 相关阅读:
    SDUT 2143 图结构练习——最短路径 SPFA模板,方便以后用。。 Anti
    SDUT ACM 1002 Biorhythms 中国剩余定理 Anti
    nyist OJ 119 士兵杀敌(三) RMQ问题 Anti
    SDUT ACM 2157 Greatest Number Anti
    SDUT ACM 2622 最短路径 二维SPFA启蒙题。。 Anti
    二叉索引树 区间信息的维护与查询 Anti
    SDUT ACM 2600 子节点计数 Anti
    UVA 1428 Ping pong 二叉索引树标准用法 Anti
    2010圣诞Google首页效果
    Object
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9572666.html
Copyright © 2011-2022 走看看