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
  • 相关阅读:
    Reactive Extensions (Rx) 入门(5) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(4) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(3) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(2) —— 安装 Reactive Extensions
    Reactive Extensions (Rx) 入门(1) —— Reactive Extensions 概要
    Xamarin NuGet 缓存包导致 already added : Landroid/support/annotation/AnimRes 问题解决方案
    Android 系统Action大全
    Xamarin Forms 实现发送通知点击跳转
    如何理解灰度发布
    推荐一款分布式微服务框架 Surging
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/13634269.html
Copyright © 2011-2022 走看看