zoukankan      html  css  js  c++  java
  • [校内训练20_09_08]AC

    1.求二元组异或的三次方的和。k为位数,nk<=2000000。

    n比较小时,直接两两枚举并用bitset计算。

    k比较小时,按照位数进行分组,那么考虑贡献(三个位置)分别在一个组、两个组、三个组里的,枚举这些组并用FWT合并。

      1 #include<bits/stdc++.h>
      2 #define fo(i,a,b)for(int i=a,_e=b;i<=_e;++i)
      3 #define fd(i,a,b)for(int i=b,_e=a;i>=_e;--i)
      4 #define ff(i,a,b)for(int i=a,_e=b;i<_e;++i)
      5 #define ul unsigned long long
      6 #define ui unsigned int
      7 using namespace std;
      8 const int N=2e6+5,mo=998244353;
      9 int tot_time;
     10 int n,k,x,_n,_k;
     11 ul ans;
     12 vector<ul>b[N][2],a[N];
     13 namespace bl_n{
     14     void work_n(){
     15         ui mul=((ul)1<<63)%mo,v;
     16         bool is=(k-1)%63>31;
     17         fo(i,1,n)
     18             fo(j,i+1,n){
     19                 v=is?(a[i][_k]^a[j][_k])%mo:a[i][_k]^a[j][_k];
     20                 fd(l,0,_k-1)
     21                     v=((ul)v*mul+(a[i][l]^a[j][l]))%mo;
     22                 ans=((ul)v*v%mo*v+ans)%mo;
     23             }
     24     }
     25 }
     26 namespace bl_bitset_k{
     27     ul is[4][N/64+5];
     28     ui _[1005];
     29     #define ct __builtin_popcountll
     30     void work_k(){
     31         _[0]=1;
     32         fo(i,1,k-1)_[i]=_[i-1]*2%mo;
     33         fo(i,0,k-1){
     34             int c[2]={0,0};
     35             fo(p,0,1)fo(j,0,_n)c[p]+=ct(b[i][p][j]);
     36             ans=((ul)_[i]*_[i]%mo*_[i]%mo*c[0]%mo*c[1]+ans)%mo;
     37             fo(l,i+1,k-1){
     38                 int c[4]={0,0,0,0};
     39                 fo(p,0,3){
     40                     int o=(p&2)>0,u=p&1;
     41                     fo(j,0,_n)is[p][j]=b[i][o][j]&b[l][u][j],c[p]+=ct(is[p][j]);
     42                 }
     43                 ans=((ul)_[i]*_[l]%mo*(_[i]+_[l])%mo*(((ul)c[0]*c[3]+(ul)c[1]*c[2])%mo)*3+ans)%mo;
     44                 fo(p,l+1,k-1){
     45                     int c[8]={0,0,0,0,0,0,0,0};
     46                     fo(o,0,3)fo(q,0,1)
     47                         fo(j,0,_n)c[o*2+q]+=ct(is[o][j]&b[p][q][j]);
     48                     ans=((ul)_[i]*_[l]%mo*_[p]%mo*(((ul)c[0]*c[7]+(ul)c[1]*c[6]+(ul)c[2]*c[5]+(ul)c[3]*c[4])%mo)*6+ans)%mo;
     49                 }
     50             }    
     51         }
     52     }
     53 }
     54 namespace divide_fwt_k{
     55     const int Q=(1<<15)+5,M=160;
     56     int f[Q],K,L;
     57     int c[M][M][M],c2[M][M],c3[M];
     58     vector<int>bit[1005];
     59     ui _[1005];
     60     bool is_do[M][M],is_do2[M];
     61     inline void up(int &x){x+=(x>>31)&mo;}
     62     int ny(int x){
     63         int t=1;
     64         fo(i,1,x)t=t&1?t+mo>>1:t>>1;
     65         return t;
     66     }
     67     void fwt_xor(int *a){
     68         int A;
     69         for(int i=1;i<(1<<K);i<<=1)for(int j=0;j<(1<<K);j+=i*2)
     70             ff(l,0,i)A=a[j+l],up(a[j+l]+=a[i+j+l]-mo),up(a[i+j+l]=A-a[i+j+l]);
     71     }
     72     void fwt_xor_and(int *a){
     73         int A;
     74         for(int i=1;i<(1<<K);i<<=1)for(int j=0;j<(1<<K);j+=i*2)
     75             ff(l,0,i)A=a[j+l],up(a[j+l]+=a[j+l]-mo),up(a[i+j+l]=A-a[i+j+l]);
     76         int y=ny(K);
     77         ff(i,0,1<<K)a[i]=(ul)a[i]*y%mo;
     78     }
     79     void ck_two_3(int x,int y,int shx,int shy){
     80         if(!is_do[x][y]){
     81             is_do[x][y]=1;
     82             ff(x0,0,L)ff(x1,x0+1,L)ff(y0,0,L)
     83                 c[x*L+x0][x*L+x1][y*L+y0]=f[(1<<x0+shx)|(1<<x1+shx)|(1<<y0+shy)];
     84             ff(x0,0,L)ff(y0,0,L)ff(y1,y0+1,L)
     85                 c[x*L+x0][y*L+y0][y*L+y1]=f[(1<<x0+shx)|(1<<y0+shy)|(1<<y1+shy)];
     86             ff(x0,0,L)ff(y0,0,L)
     87                 c2[x*L+x0][y*L+y0]=f[(1<<x0+shx)|(1<<y0+shy)];
     88         }
     89     }
     90     void ck_one_3(int x,int shx){
     91         if(!is_do2[x]){
     92             is_do2[x]=1;
     93             ff(x0,0,L)ff(x1,x0+1,L)ff(x2,x1+1,L)
     94                 c[x*L+x0][x*L+x1][x*L+x2]=f[(1<<x0+shx)|(1<<x1+shx)|(1<<x2+shx)];
     95             ff(x0,0,L)ff(x1,x0+1,L)
     96                 c2[x*L+x0][x*L+x1]=f[(1<<x0+shx)|(1<<x1+shx)];
     97             ff(x0,0,L)
     98                 c3[x*L+x0]=f[(1<<x0+shx)];
     99         }
    100     }
    101     void init(){
    102         for(;(ul)3*(L+1)*(1<<3*(L+1))<=n;)++L;L=min(L,5);
    103     }
    104     void work_k(){
    105         init();
    106         K=L*3;
    107         int G=(k-1)/L;
    108         fo(j,0,G){
    109             int S=j*L,E=(j+1)*L-1,L2=64-(S&63);
    110             bit[j].resize(n+1);
    111             fo(i,1,n)
    112                 bit[j][i]=(S>>6)==(E>>6)?a[i][S>>6]>>(S&63)&((1<<L)-1):(a[i][S>>6]>>(S&63))|(a[i][E>>6]&((1<<L-L2)-1))<<L2;
    113         }
    114         fo(j,0,G)fo(l,j+1,G)fo(p,l+1,G){
    115             memset(f,0,1<<K+2);
    116             fo(i,1,n)++f[(bit[j][i]<<L*2)|(bit[l][i]<<L)|bit[p][i]];
    117             fwt_xor(f);
    118             ff(i,0,1<<K)f[i]=(ul)f[i]*f[i]%mo;
    119             fwt_xor_and(f);
    120             ff(j0,0,L)ff(l0,0,L)ff(p0,0,L)
    121                 c[j*L+j0][l*L+l0][p*L+p0]=f[(1<<j0+L*2)|(1<<l0+L)|(1<<p0)];
    122             ck_two_3(j,l,L*2,L);
    123             ck_two_3(j,p,L*2,0);
    124             ck_two_3(l,p,L,0);
    125             ck_one_3(j,L*2);
    126             ck_one_3(l,L);
    127             ck_one_3(p,0);
    128         }
    129         _[0]=1;
    130         fo(i,1,k-1)_[i]=_[i-1]*2%mo;
    131         fo(i,0,k-1){
    132             ans=((ul)_[i]*_[i]%mo*_[i]%mo*c3[i]+ans)%mo;
    133             fo(l,i+1,k-1){
    134                 ans=((ul)_[i]*_[l]%mo*(_[i]+_[l])%mo*c2[i][l]*3+ans)%mo;
    135                 fo(p,l+1,k-1)
    136                     ans=((ul)_[i]*_[l]%mo*_[p]%mo*c[i][l][p]*6+ans)%mo;
    137             }
    138         }
    139         ans=ans*(mo+1>>1)%mo;
    140     }
    141 }
    142 ui seed;
    143 #define get_next()(seed^=seed<<13,seed^=seed>>17,seed^=seed<<5)
    144 int main(){
    145     freopen("xor.in","r",stdin);
    146     freopen("xor.out","w",stdout);
    147     cin>>n>>k>>x>>seed;
    148     _n=n>>6;
    149     if(k<=150){
    150         divide_fwt_k::init();
    151         if(!divide_fwt_k::L||(k-1)/divide_fwt_k::L<2){
    152             _k=k-1>>6;
    153             fo(i,0,k-1)fo(o,0,1)b[i][o].resize(_n+1);
    154             fo(i,1,n){
    155                 a[i].resize(_k+1);
    156                 fo(j,0,k-1){
    157                     get_next();
    158                     if(seed&1)
    159                         a[i][j>>6]|=(ul)1<<(j&63),b[j][1][i>>6]|=(ul)1<<(i&63);
    160                     else 
    161                         b[j][0][i>>6]|=(ul)1<<(i&63);    
    162                 }
    163             }
    164             bl_bitset_k::work_k();
    165         }else{
    166             _k=k-1>>6;
    167             fo(i,1,n){
    168                 a[i].resize(_k+1);
    169                 fo(j,0,k-1){
    170                     get_next();
    171                     if(seed&1)
    172                         a[i][j>>6]|=(ul)1<<(j&63);
    173                 }
    174             }
    175             divide_fwt_k::work_k();
    176         }
    177     }else{
    178         _k=(k-1)/63;
    179         fo(i,1,n){
    180             a[i].resize(_k+1);
    181             fo(j,0,k-1){
    182                 get_next();
    183                 if(seed&1)
    184                     a[i][j/63]|=(ul)1<<(j%63);
    185             }
    186         }
    187         bl_n::work_n();
    188     }
    189     cout<<ans<<endl;
    190 }
    View Code

    3.确定一个排列,每次可以询问一个排列,返回正确的位置的个数。要求nlogn次询问。

    只考虑n为偶数的情况。对于两个位置i和j,如果交换以后询问从0变为1或2,那么i和j中至少有一个位置上应为p[i]或p[j]。这样,连边所有询问会从0变为1或2的点对(i,j),最后图一定由环构成,定向以后就确定了排列。

    考虑选出一些没有公共点的边,将这些边的两端进行交换后,如果询问从0变为了一个正数,那么这些边中至少有一条出现在环中的边。这样就能进行二分找到有用的边。

    进行n-1轮,每次需要找到n/2条边,有这样一种构造:从0开始标号,第x轮选择i+j=x(mod n-1)的点对和2p=x(mod n-1)的点对。

    如果是奇数,多加一个点。

     1 #include "game.h"
     2 #include<bits/stdc++.h>
     3 #define fo(i,a,b)for(int i=a,_e=b;i<=_e;++i)
     4 #define fd(i,a,b)for(int i=b,_e=a;i>=_e;--i)
     5 #define P pair<int,int>
     6 #define fi first
     7 #define se second
     8 #define pb push_back
     9 #define ll long long
    10 #define add(x,y)(su[x]<2&&su[y]<2?d.pb(P(x,y)),0:0)
    11 using namespace std;
    12 const int N=10005;
    13 int n,lim,nn,cs,las,now,su[N];
    14 vector<int>ans,a,q,e[N];
    15 vector<int>c[N];
    16 vector<P>d;
    17 bool us[N];
    18 int ran(int x,int y){return ((ll)RAND_MAX*rand()+rand())%(y-x+1)+x;}
    19 void shuffle(vector<int> &a){
    20     fo(i,0,n-1)swap(a[i],a[ran(0,i)]);
    21 }
    22 void link(int x,int y,int ct){
    23     e[x].pb(y);e[y].pb(x);
    24     su[x]+=ct;su[y]+=ct;
    25 }
    26 int get(int l,int r){
    27     q=a;
    28     fo(i,l,r)swap(q[d[i].fi-1],q[d[i].se-1]);
    29     return count(q);
    30 }
    31 void find(int l,int r,int cnt){
    32     if(!cnt)return;
    33     if(l==r){
    34         link(d[l].fi,d[l].se,cnt);
    35         return;
    36     }
    37     int m=l+r>>1,cnt2=get(l,m);
    38     find(l,m,cnt2);
    39     find(m+1,r,cnt-cnt2);
    40 }
    41 void dg(int x){
    42     us[x]=1;c[cs].pb(x-1);
    43     for(int i:e[x])if(!us[i])dg(i);
    44 }
    45 std :: vector<int> guess(int _n, int _limit) {
    46     srand(998244353);
    47 //    srand(time(0)+*(new(int)));
    48     n=_n;lim=_limit;
    49     fo(i,1,n)a.pb(i);
    50     for(;;){
    51         shuffle(a);
    52         if(!count(a))break;
    53     }
    54     nn=n&1?n:n-1;
    55     fo(i,0,nn-1){
    56         d.clear();
    57         fo(j,0,nn-1){
    58             int x=j+1,y=(i-j+nn)%nn+1;
    59             if(x==y&&(~n&1))add(x,n);
    60             else{
    61                 if(x<y)add(x,y);
    62             }
    63         }
    64         if(d.size())
    65             find(0,d.size()-1,get(0,d.size()-1));
    66     }
    67     fo(i,1,n)if(!us[i])++cs,dg(i);
    68     ans=a;
    69     fo(i,1,cs){
    70         int s=c[i].size();
    71         fo(j,0,s-1)ans[c[i][j]]=a[c[i][(j+1)%s]];
    72         now=count(ans);
    73         if(las==now){
    74             fo(j,0,s-1)ans[c[i][j]]=a[c[i][(j+s-1)%s]];
    75             now+=s;
    76         }
    77         las=now;
    78     }
    79     return ans;
    80 }
    View Code
  • 相关阅读:
    [XNA]2D图形概要(2D Graphics Overview)
    [WP7]WindowsPhone支持VS2010的开发工具出来了
    [WM]用双缓冲在CStatic上面画
    [读书]至理名言摘自你的灯还亮着吗
    无题!!
    Windows 8 Consumer Preview 中的快捷键
    aptana studio 汉化与安装 zencoding、配置
    jQuery常用焦点图,可做选项卡切换
    jQuery 导航点击变换样式
    原生JS:焦点图 左右滚动
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/13634269.html
Copyright © 2011-2022 走看看