20180516小测


T1:


我们能够证明(显然)这样的一个网络能输出任何[0,2^n-1]的排列(可以用归纳法证明),于是-1是不存在的了。
考虑每个节点只有两种状态,能否2-sat做呢?似乎有一些节点的状态是存在依赖关系的,然而并不会建图。
(于是我就写了20分暴力,先枚举那些节点激活然后进行大模拟)
正解是考虑这个网络的形态,观察可得一个节点输出的两个信号会被分配到左右的两个子网络中。
如果我们想构造出解的话,需要让第一次每个节点的两个信号进入两个不同的子网络,最后一层每个节点的两个信号从两个不同的子网络中得来。这个就是依赖关系了。
等等,这个似乎不需要2-sat,因为要字典序最小,我们能钦定第一行第一个节点状态为0,然后通过数值关系推出每个数字必须在哪个子网络中,这样与1号节点存在依赖关系的节点的状态也就都确定了。
然后继续扫描第一行,如果存在某个节点的状态没有被确定,那么让他为0与前面最优化的答案一定不冲突,我们就让他为0,然后继续递推就好了。
然后完成某一级的答案求解后,递归求出两个子网络的状态即可。
复杂度O(n*2^n)。

20分暴力代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 const int maxn=11;
 4 const int inf=0x3f3f3f3f;
 5 
 6 bool sta[maxn][maxn];
 7 int in[maxn][maxn],tar[maxn],Log[maxn];
 8 
 9 inline int shl(int x,int l) {
10     int ret = 0;
11     for(int i=0;i<l;i++) if( x & ( 1 << i ) ) ret |= 1 << ( ( i - 1 + l ) % l );
12     return ret;
13 }
14 inline int shr(int x,int l) {
15     int ret = 0;
16     for(int i=0;i<l;i++) if( x & ( 1 << i ) ) ret |= 1 << ( ( i + 1 ) % l );
17     return ret;
18 }
19 
20 inline void solve(int x,int y,int z,int inlev,int outlev,int n) { // doubled data level .
21     if( n == 1 ) return;
22     for(int i=0;i<n>>1;i++) { // cross node from inlev to inlev + 1 .
23         int l = y + i * 2 , r = y + i * 2 + 1;
24         in[inlev+1][l] = in[inlev][l] , in[inlev+1][r] = in[inlev][r];
25         if( sta[x][(y>>1)+i] ) std::swap(in[inlev+1][l],in[inlev+1][r]);
26     }
27     if( n != 2 ) {
28         for(int i=0;i<n>>1;i++) { // cross line from inlev + 1 to inlev + 2 .
29             int ix = y + i * 2 , iy = y + i * 2 + 1 , ox = y + shl(i*2,Log[n]) , oy = y + shl(i*2+1,Log[n]);
30             in[inlev+2][ox] = in[inlev+1][ix] , in[inlev+2][oy] = in[inlev+1][iy];
31         }
32         solve(x+1,y,z-1,inlev+2,outlev-2,n>>1) , solve(x+1,y+(n>>1),z-1,inlev+2,outlev-2,n>>1);
33         for(int i=0;i<n>>1;i++) { // cross line from outlev - 1 to outlev .
34             int ix = y + i * 2 , iy = y + i * 2 + 1 , ox = y + shr(i*2,Log[n]) , oy = y + shr(i*2+1,Log[n]);
35             in[outlev][ox] = in[outlev-1][ix] , in[outlev][oy] = in[outlev-1][iy];
36         }
37     }
38     for(int i=0;i<n>>1;i++) { // cross node from outlev to outlev + 1.
39         int l = y + i * 2 , r = y + i * 2 + 1;
40         in[outlev+1][l] = in[outlev][l] , in[outlev+1][r] = in[outlev][r];
41         if( sta[z][(y>>1)+i] ) std::swap(in[outlev+1][l],in[outlev+1][r]);
42     }
43 }
44 
45 inline bool dif(int n,int n_lev) {
46     for(int i=0;i<1<<n;i++) if( in[n_lev][i] != tar[i] ) return 1;
47     return 0;
48 }
49 inline void unzipsta(int ss,int x,int y) {
50     for(int i=x-1;~i;i--) for(int j=y-1;~j;j--) sta[i][j] = ss & 1 , ss >>= 1;
51 }
52 
53 int main()
54     static int sol,n,full,n_nod,m_nod,n_lev;
55     while( scanf("%d",&n) == 1 && n ) {
56         sol = 0 , n_nod = 2 * n - 1 , m_nod = 1 << ( n - 1 ) , n_lev = 2 * n_nod - 1 , full = 1 << ( n_nod * m_nod );
57         for(int i=0;i<=n;i++) Log[1<<i] = i;
58         for(int i=0;i<1<<n;i++) scanf("%d",tar+i);
59         for(int i=0;i<full&&!sol;i++) {
60             for(int j=0;j<1<<n;j++) in[0][j] = j;
61             unzipsta(i,n_nod,m_nod) , solve(0,0,n_nod-1,0,n_lev-1,1<<n);
62             if( !dif(n,n_lev) ) sol = 1;
63         }
64         if( !sol ) puts("-1");
65         else {
66             for(int i=0;i<n_nod;i++) {
67                 for(int j=0;j<m_nod;j++) putchar('0'+sta[i][j]);
68                 putchar('\n');
69             }
70         }
71         putchar('\n');
72     }
73     return 0;
74 }
View Code

正解代码:
(原谅我代码写得像天书一样)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define debug cout
using namespace std;
const int maxe=30,maxn=1<<14;

bool ans[maxe][maxn];
int in[maxe][maxn],Log[maxn];
int lim[maxn],app[maxn],rapp[maxn];
int n,nod_n,nod_m,data_m;

inline int shl(int x,int l) { // looping bit left move .
    int ret = 0;
    for(int i=0;i<l;i++) if( x & ( 1 << i ) ) ret |= 1 << ( ( i - 1 + l ) % l );
    return ret;
}
inline int shr(int x,int l) { // looping bit right move .
    int ret = 0;
    for(int i=0;i<l;i++) if( x & ( 1 << i ) ) ret |= 1 << ( ( i + 1 ) % l );
    return ret;
}

inline void dfs(int inlev,int outlev,int cur,int pos) { // cur = 0 or 1 means up or down .
    int oth = pos ^ 1;
    if( !cur ) { // solve by inklev .
        if( !~lim[in[inlev][oth]] ) lim[in[inlev][oth]] = lim[in[inlev][pos]] ^ 1 , dfs(inlev,outlev,0,oth);
        int op = app[in[inlev][pos]] , oop = op ^ 1;
        if( !~lim[in[outlev][oop]] ) lim[in[outlev][oop]] = lim[in[outlev][op]] ^ 1 , dfs(inlev,outlev,1,oop);
    } else {
        if( !~lim[in[outlev][oth]] ) lim[in[outlev][oth]] = lim[in[outlev][pos]] ^ 1 , dfs(inlev,outlev,1,oth);
        int op = rapp[in[outlev][pos]] , oop = op ^ 1;
        if( !~lim[in[inlev][oop]] ) lim[in[inlev][oop]] = lim[in[inlev][op]] ^ 1 , dfs(inlev,outlev,0,oop);
    }
}
inline void solve(int sx,int sy,int tx,int inlev,int outlev,int n) { // n is count of points , n >> 1 is count of nodes , sx and sy are position of nodes .
    if( n == 2 ) {
        if( in[inlev][sy<<1] != in[outlev][sy<<1] ) ans[sx][sy] = 1;
        return;
    }
    
    for(int i=0;i<n;i++) lim[in[inlev][(sy<<1)+i]] = -1;
    for(int i=0;i<n;i++) app[in[outlev][(sy<<1)+i]] = (sy<<1)+i , rapp[in[inlev][(sy<<1)+i]] = (sy<<1)+i;
    const int mid = ( sy << 1 ) + ( n >> 1 ) - 1;
    
    for(int i=0;i<n>>1;i++) {
        int l = (sy<<1) + (i<<1) , r = (sy<<1) + (i<<1|1) , tl = (sy<<1) + shl(i<<1,Log[n]) , tr = (sy<<1) + shl(i<<1|1,Log[n]);
        if( !~lim[in[inlev][l]] && !~lim[in[inlev][r]] ) lim[in[inlev][l]] = tl > mid , lim[in[inlev][r]] = tr > mid; // left 0 , right 1 .
        else { // solve limit .
            if( ~lim[in[inlev][l]] ) lim[in[inlev][r]] = lim[in[inlev][l]] ^ 1;
            else lim[in[inlev][l]] = lim[in[inlev][r]] ^ 1;
            ans[sx][sy+i] = ( tl > mid ) ^ lim[in[inlev][l]];
        }
        dfs(inlev,outlev,0,l) , dfs(inlev,outlev,0,r);
        
        int pl = app[in[inlev][l]] , bpl = ( pl - (sy<<1) ) >> 1 , bpl_l = (sy<<1) + (bpl<<1) , bpl_l_tarsou = (sy<<1) + shl(bpl<<1,Log[n]);
        ans[tx][sy+bpl] = ( bpl_l_tarsou > mid ) ^ lim[in[outlev][bpl_l]];
        
        int pr = app[in[inlev][r]] , bpr = ( pr - (sy<<1) ) >> 1 , bpr_l = (sy<<1) + (bpr<<1) , bpr_l_tarsou = (sy<<1) + shl(bpr<<1,Log[n]);
        ans[tx][sy+bpr] = ( bpr_l_tarsou > mid ) ^ lim[in[outlev][bpr_l]];
        
    }
    
    for(int i=0;i<n>>1;i++) { // trans data to next level .
        int l = (sy<<1) + (i<<1) , r = (sy<<1) + (i<<1|1) , tl = (sy<<1) + shl(i<<1,Log[n]) , tr = (sy<<1) + shl(i<<1|1,Log[n]);
        in[inlev+1][tl] = in[inlev][l] , in[inlev+1][tr] = in[inlev][r];
        if(ans[sx][sy+i]) swap(in[inlev+1][tl],in[inlev+1][tr]);
    }
    for(int i=0;i<n>>1;i++) { // trans data to previous level .
        int l = (sy<<1) + (i<<1) , r = (sy<<1) + (i<<1|1) , fl = (sy<<1) + shl(i<<1,Log[n]) , fr = (sy<<1) + shl(i<<1|1,Log[n]);
        in[outlev-1][fl] = in[outlev][l] , in[outlev-1][fr] = in[outlev][r];
        if(ans[tx][sy+i]) swap(in[outlev-1][fl],in[outlev-1][fr]);
    }
    
    solve(sx+1,sy,tx-1,inlev+1,outlev-1,n>>1) , solve(sx+1,sy+(n>>2),tx-1,inlev+1,outlev-1,n>>1);
}

inline void reset() {
    memset(ans,0,sizeof(ans));
}

int main() {
    while( scanf("%d",&n) == 1 && n ) {
        reset() , nod_n = ( n << 1 ) - 1 , nod_m = 1 << ( n - 1 ) , data_m = 1 << n;
        for(int i=0;i<=n;i++) Log[1<<i] = i;
        for(int i=0;i<data_m;i++) in[0][i] = i , scanf("%d",in[nod_n]+i);
        solve(0,0,nod_n-1,0,nod_n,data_m);
        for(int i=0;i<nod_n;i++) {
            for(int j=0;j<nod_m;j++) putchar('0'+ans[i][j]);
            putchar('\n');
        }
        putchar('\n');
    }
    return 0;
}
View Code

 


T2:

观察这个生成的序列,发现没什么性质(没错,它最大的性质就是随机!)。
于是没什么好办法,只好用数据结构做了。
平衡树和线段树是不用想了,铁定TLE(线段树还会MLE),我们需要一个更优美的做法。
用堆!一个大根堆维护序列的前半部分,一个小根堆维护序列的后半部分。
每次把新生成的数插入前半部分的大根堆,当这个堆的大小比(i+1)/2大时,弹出堆顶并把堆顶放进后半部分的小根堆。
如果当前大根堆堆顶比小根堆堆顶大的话,我们就交换这两个堆顶的元素(两个push两个pop)。
显然对于插入的每个数字,第一种操作只会进行1次,对于每一个i,第二种操作只会进行O(1)次,总复杂度O(nlogn)。
很不幸的是,这样做也只有50分,即使你用pb_ds的配对堆或斐波那契堆。
考虑复杂度瓶颈在哪里,我们每次对堆进行操作的时候,都要承受一个巨大的log。
好的,我们还是维护两个堆,在中间维护一棵平衡树作为缓存,保证当前查询的那个数值永远在平衡树里。用这棵平衡树减少堆的操作并限制它的大小来减小log,是不是就能卡过去了呢?
具体操作就是,插入的时候判断新加的值在那一段,加入正确的位置;
当平衡树的大小和第一个堆大小的和比当前要查询的数值小时,从第二个堆中取出数字放进平衡树中;
当平衡树的大小比阈值大时,把平衡树开始或结尾的元素移动到大小较小的那个堆中。
因为数据随机,所以如果平衡树缓存大小合适,我们对两边的堆的操作会大幅度减少,于是就可以AC了。

50分暴力代码:

 1 #pragma GCC optimize("Ofast")
 2 #pragma GCC target("avx")
 3 #pragma GCC optimize("no-stack-protector")
 4 #include<cstdio>
 5 #include<ext/pb_ds/priority_queue.hpp>
 6 #define ull unsigned long long
 7 using namespace std;
 8 using namespace __gnu_pbds;
 9 const unsigned mod=1e9+7;
10  
11 __gnu_pbds::priority_queue<unsigned,less<unsigned>,binary_heap_tag> exs;
12 __gnu_pbds::priority_queue<unsigned,greater<unsigned>,binary_heap_tag> del;
13 
14 __inline unsigned gen(const unsigned &t,const unsigned &ans) {
15     return ( 714636908ull * t % mod + 681692770u ) * ( 846930886ull * ans % mod + 804289376u ) % mod;
16 }
17 
18 int main() {
19     static unsigned n,t,ans,out;
20     scanf("%u%u",&n,&t);
21     for(register unsigned i=1,p=1;i<=n;i++,p=(i+1)>>1) {
22         exs.push(t);
23         while( exs.size() > p ) del.push(exs.top()) , exs.pop();
24         while( del.size() && del.top() < exs.top() ) exs.push(del.top()) , del.pop() , del.push(exs.top()) , exs.pop();
25         ans = exs.top() , out ^= ans , t = gen(t,ans);
26     }
27     printf("%u\n",out);
28     return 0;
29 }
View Code

正解代码:

 1 /*#pragma GCC optimize("Ofast")
 2 #pragma GCC target("avx")
 3 #pragma GCC optimize("no-stack-protector")*/
 4 #include<cstdio>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<vector>
 8 #include<ext/pb_ds/tree_policy.hpp>
 9 #include<ext/pb_ds/assoc_container.hpp>
10 typedef unsigned long long int ulli;
11 const int mod=1e9+7;
12 const int lim=10;
13 
14 std::priority_queue<ulli,std::vector<ulli>,std::less<ulli> > lft;
15 std::priority_queue<ulli,std::vector<ulli>,std::greater<ulli> > rit;
16 __gnu_pbds::tree<ulli,__gnu_pbds::null_type,std::less<ulli>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update> buf;
17 
18 __inline unsigned gen(const unsigned &t,const unsigned &ans) {
19     return ( 714636908ull * t % mod + 681692770u ) * ( 846930886ull * ans % mod + 804289376u ) % mod;
20 }
21 
22 int main() {
23     static unsigned n,t,ans,out;
24     scanf("%u%u",&n,&t);
25     for(register unsigned i=1,p;i<=n;i++) {
26         p = ( i + 1 ) >> 1;
27         register ulli cur = (ulli) t * ( mod + 1 ) + i;
28         if( buf.size() && cur < *buf.begin() ) lft.push(cur);
29         else if( buf.size() && cur > *buf.rbegin() ) rit.push(cur);
30         else buf.insert(cur);
31         while( p > lft.size() + buf.size() ) buf.insert(rit.top()) , rit.pop();
32         while( p <= lft.size() ) buf.insert(lft.top()) , lft.pop();
33         out ^= ans = *buf.find_by_order(p-lft.size()-1) / ( mod + 1 ) ;
34         t = gen(t,ans);
35         while( buf.size() > lim ) {
36             if( lft.size() < rit.size() ) lft.push(*buf.begin()) , buf.erase(buf.begin());
37             else rit.push(*buf.rbegin()) , buf.erase(buf.rbegin());
38         }
39     }
40     printf("%u\n",out);
41     return 0;
42 }
View Code

 


T3:


博弈论+数据结构?
SG函数怎么推啊......只知道P为奇数时,SG值为当前元素的奇偶性。数据不保证P的奇偶,写了也不一定有分,弃疗了。
假设我们打表观察(出题人写的)这个题的SG函数是这样的:
当P为奇数时,大小为n的堆的SG值为 n mod 2。
当P为偶数时,大小为n的堆的SG值为:
如果 n mod P + 1 = P , 则为2;
否则为 n mod P + 1 mod 2。
考虑怎么证明。
P为奇数时的SG值显然,因为每次操作一定改变堆大小的奇偶性。
P为偶数时的证明就比较麻烦了......
因为a^2-1=(a+1)*(a-1),故 a^2-1+1=(a+1)*(a-1)+1 = 1 mod a+1 , 所以 a^3 = a * a^2 = a mod a+1。
所以,取p^k的情况,在mod p+1下都能划归为取1或者取p的情况。
所以我们可以在P+1的同余系下做。如果 mod P+1 < P 的话,只能取1,所以SG值为 n mod P + 1 mod 2 。
而mod P+1 = P的情况,我们可以取p,到SG值为0的状态0和SG值为1的状态P-1,故这个状态的SG值为mex(1,2)=2。

于是我们对于P为奇数和偶数的情况分别计算。
P为奇数的话,相当于区间 xor 1,求区间 xor 和,线段树轻松搞定。
P为偶数的情况,我们需要分块。
考虑我们先让所有数值mod P+1再按照mod 2将这些数值放入两个有序数组里。
那么,如果区间同时加上add,所有>=P+1-add的数会溢出一轮。
如果add为偶数的话,溢出的数的奇偶性改变,没溢出的数的奇偶性不变;
如果add为奇数的话,溢出的数的奇偶性不变,没溢出的数的奇偶性改变。
这样我们维护两个有序数组每次lower_bound一下就好了,当然如果你非得写平衡树也没人拦你。
(什么?mod P+1 = P的?满足这种情况的只有一个数就是P+1-add,我们用一个map存mod P+1为某个数的值有多少个,再手动从奇偶两种减去这个值的贡献就好了)

代码:

  1 #pragma GCC optimize("Ofast")
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<map>
  5 #include<vector>
  6 #include<cmath>
  7 const int maxn=1e5+1e2,maxe=325;
  8 
  9 int n,m,a;
 10 
 11 namespace Even {
 12     int dat[maxn],bel[maxn],st[maxe],ed[maxe],add[maxe];
 13     std::vector<int> cont[maxe][2];
 14     std::map<int,int> app[maxe];
 15     
 16     inline void rebuild(int id) {
 17         cont[id][0].clear() , cont[id][1].clear() , app[id].clear();
 18         for(int i=st[id];i<=ed[id];i++) cont[id][dat[i]&1].push_back(dat[i]) , ++app[id][dat[i]];
 19         std::sort(cont[id][0].begin(),cont[id][0].end()) , std::sort(cont[id][1].begin(),cont[id][1].end());
 20     }
 21     inline void partadd(int id,int l,int r,const int &x) {
 22         l = std::max( l , st[id] ) , r = std::min( r , ed[id] );
 23         for(int i=l;i<=r;i++) dat[i] = ( dat[i] + x ) % ( a + 1 );
 24     }
 25     inline void push(int id) {
 26         if( add[id] ) partadd(id,st[id],ed[id],add[id]) , add[id] = 0;
 27     }
 28     inline void fulladd(int id,const int &x) {
 29         add[id] = ( add[id] + x ) % ( a + 1 );
 30     }
 31     inline void modify(int l,int r,const int &x) {
 32         if( bel[l] == bel[r] ) push(bel[l]) , partadd(bel[l],l,r,x) , rebuild(bel[l]);
 33         else {
 34             push(bel[l]) , partadd(bel[l],l,r,x) , rebuild(bel[l]);
 35             for(int i=bel[l]+1;i<bel[r];i++) fulladd(i,x);
 36             push(bel[r]) , partadd(bel[r],l,r,x) , rebuild(bel[r]);
 37         }
 38     }
 39     
 40     inline int partquery(int id,int l,int r) {
 41         int ret = 0; l = std::max( l , st[id] ) , r = std::min( r , ed[id] );
 42         for(int i=l,t;i<=r;i++) t = ( dat[i] + add[id] ) % ( a + 1 ) , ret ^= ( t == a ? 2 : ( t & 1 ) );
 43         return ret;
 44     }
 45     inline int fullquery(int id) {
 46         int siz0=0,siz1=0,siz2=0,ned=a-add[id];
 47         int p0 = std::lower_bound(cont[id][0].begin(),cont[id][0].end(),a+1-add[id]) - cont[id][0].begin();
 48         int p1 = std::lower_bound(cont[id][1].begin(),cont[id][1].end(),a+1-add[id]) - cont[id][1].begin();
 49         siz0 += p0 , siz1 += p1 , siz0 += cont[id][1].size() - p1 , siz1 += cont[id][0].size() - p0 , siz2 = app[id][ned];
 50         ( ned & 1 ? siz1 : siz0 ) -= siz2;
 51         if( add[id] & 1 ) std::swap(siz0,siz1);
 52         return ( siz1 & 1 ) ^ ( ( siz2 & 1 ) << 1 );
 53     }
 54     inline int query(int l,int r) {
 55         if( bel[l] == bel[r] ) return partquery(bel[l],l,r);
 56         int ret = partquery(bel[l],l,r) ^ partquery(bel[r],l,r);
 57         for(int i=bel[l]+1;i<bel[r];i++) ret ^= fullquery(i);
 58         return ret;
 59     }
 60     
 61     inline void init() {
 62         for(int i=1;i<=n;i++) dat[i] %= a+1;
 63         int sq = sqrt(n) , cnt = 0;
 64         for(int l=1,r;l<=n;l=r+1) {
 65             r = std::min( l + sq - 1 , n ) , st[++cnt] = l , ed[cnt] = r;
 66             for(int i=l;i<=r;i++) bel[i] = cnt;
 67             rebuild(cnt);
 68         }
 69     }
 70     inline void main() {
 71         for(int i=1;i<=n;i++) scanf("%d",dat+i);
 72         init();
 73         for(int i=1,o,l,r,x;i<=m;i++) {
 74             scanf("%d%d%d",&o,&l,&r);
 75             if( o == 1 ) puts(query(l,r)?"1":"0");
 76             else scanf("%d",&x) , modify(l,r,x);
 77         }
 78     }
 79 }
 80 
 81 namespace Odd {
 82     int dat[maxn],siz[maxn<<2][2],lazy[maxn<<2];
 83     
 84     #define lson(pos) (pos<<1)
 85     #define rson(pos) (pos<<1|1)
 86     
 87     inline void build(int pos,int l,int r) {
 88         if( l == r ) return void( siz[pos][dat[l]&1] = 1 );
 89         const int mid = ( l + r ) >> 1;
 90         build(lson(pos),l,mid) , build(rson(pos),mid+1,r) ,
 91         siz[pos][0] = siz[lson(pos)][0] + siz[rson(pos)][0] , siz[pos][1] = siz[lson(pos)][1] + siz[rson(pos)][1];
 92     }
 93     inline void apply(int pos) {
 94         lazy[pos] ^= 1 ,  std::swap(siz[pos][0],siz[pos][1]);
 95     }
 96     inline void push(int pos) {
 97         if( lazy[pos] ) apply(lson(pos)) , apply(rson(pos)) , lazy[pos] = 0;
 98     }
 99     inline void update(int pos,int l,int r,const int &ll,const int &rr) {
100         if( ll <= l && r <= rr ) return apply(pos);
101         const int mid = ( l + r ) >> 1; push(pos);
102         if( ll <= mid ) update(lson(pos),l,mid,ll,rr);
103         if( mid < rr ) update(rson(pos),mid+1,r,ll,rr);
104         siz[pos][0] = siz[lson(pos)][0] + siz[rson(pos)][0] , siz[pos][1] = siz[lson(pos)][1] + siz[rson(pos)][1];
105     }
106     inline int query(int pos,int l,int r,const int &ll,const int &rr) {
107         if( ll <= l && r <= rr ) return siz[pos][1] & 1;
108         const int mid = ( l + r ) >> 1; push(pos);
109         if( rr <= mid ) return query(lson(pos),l,mid,ll,rr);
110         else if( ll > mid ) return query(rson(pos),mid+1,r,ll,rr);
111         return query(lson(pos),l,mid,ll,rr) ^ query(rson(pos),mid+1,r,ll,rr);
112     }
113     inline void main() {
114         for(int i=1;i<=n;i++) scanf("%d",dat+i);
115         build(1,1,n);
116         for(int i=1,o,l,r,x;i<=m;i++) {
117             scanf("%d%d%d",&o,&l,&r);
118             if( o == 1 ) puts(query(1,1,n,l,r)?"1":"0");
119             else {
120                 scanf("%d",&x);
121                 if( x & 1 ) update(1,1,n,l,r);
122             }
123         }
124     }
125 }
126 
127 int main() {
128     scanf("%d%d%d",&n,&m,&a);
129     if( a & 1 ) Odd::main();
130     else Even::main();
131     return 0;
132 }
View Code

 



流れる雲間に指先重ねて
流云间十指相扣
隠した何時かと 同じ色の陽を
埋藏着与那个时候同色的阳光
光を追いかけ 知らない街を
我于不曾知晓的街道上追逐着那束光芒
独りで歩いた 又逢う日夢見て
独自一人行走 而又回想起相遇的那天
伝えたいよ 忘れられないあの景色も
想要告诉你 那道难以忘怀的风景
今は瞳の奥に色褪せないように
如今也仍在眼眸深处不曾褪色
空を辿る路 足跡一つでも
追寻着天空的路上 只存留着我的足迹
この時のはてに貴方が若し居るなら
如果这个时候有你在我身旁的话
少しだけで好い 彷徨う私にも
哪怕只有一点点 即使是处于彷徨中的我
彼方から風の唄を届けて
也听见了从远方传来的风之歌

posted @ 2018-05-17 00:35  Cmd2001  阅读(263)  评论(0编辑  收藏  举报