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
  • 相关阅读:
    021.day21 反射 Class类 反射常用操作
    020.day20 线程概述 多线程优缺点 线程的创建 线程常用方法 生命周期 多线程同步
    019.day19 缓冲流 对象流 标准输入输出流
    018.day18 map集合如何实现排序 File类 IO流 字节流 字符流 编码
    017.day17 Map接口 克隆 treeSet集合排重缺陷
    016.day16 HashSet TreeSet 比较器Comparable Comparator
    015.day15
    014.day14
    013.day13
    线程
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/13634269.html
Copyright © 2011-2022 走看看