1 条题解

  • 0
    @ 2025-8-24 22:29:54

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 0x3F
    Wir müssen wissen, wir werden wissen.

    搬运于2025-08-24 22:29:54,当前版本为作者最后更新于2021-03-24 22:34:02,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    最开始时由于某些原因这题是第一题。

    我做了半个小时才做出来,心想第一题都这么难,第二题肯定做不出来了。

    结果只花了 55 分钟就做出了 “第二题”。

    进入正题:

    先考虑 11 操作。

    以长度为 23=82^3 = 8 的序列为例。

    初始序列:

    十进制 二进制
    00 000000
    11 001001
    22 010010
    33 011011
    44 100100
    55 101101
    66 110110
    77 111111

    操作后:

    十进制 二进制
    00 000000
    22 010010
    44 100100
    66 110110
    11 001001
    33 011011
    55 101101
    77 111111

    再次操作:

    十进制 二进制
    00 000000
    44 100100
    11 001001
    55 101101
    22 010010
    66 110110
    33 011011
    77 111111

    观察它们的二进制有什么规律?

    我们发现一次操作相当于将二进制首位移到末位,其他位向左移一格

    也就是说,将二进制的各位按顺时针连成一个环,并将该环逆时针旋转一格

    开一个变量记一下旋转的次数即可。

    如果旋转了整整一圈,一定记得要归零!!!

    再来看一下 22 操作: | 11 操作 | 二进制 | 22 操作 | 二进制 | | :-----------: | :-----------: | :-----------: | :-----------: | | 00 | 000000 | 11 | 001001 | | 22 | 010010 | 33 | 011011 | | 44 | 100100 | 55 | 101101 | | 66 | 110110 | 77 | 111111 | | 11 | 001001 | 00 | 000000 | | 33 | 011011 | 22 | 010010 | | 55 | 101101 | 44 | 100100 | | 77 | 111111 | 66 | 110110 |

    不就是 xor\operatorname{xor} 一下 11 吗?

    另开一个变量记一下xor\bold{xor} 的数即可。

    用位运算,Θ(m)\Theta(m),比大伙们的 Θ(nm)\Theta(nm) 快多了。

    还有:

    unsigned int

    因为:

    x[0,232)x \in [0, 2^{32})

    int 的表示范围为

    [231,231)[-2^{31}, 2^{31})

    你用 long long 没人拦着你

    #include <bits/stdc++.h>
    using namespace std;
    int n, m, o;
    unsigned x, y;
    
    inline unsigned read(){
       int s=0,w=1;
       char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
       return s*w;
    }
    
    inline void write(unsigned x)
    {
        if(x>9) write(x/10);
        putchar(x%10+48);
    }
    
    int cnt;
    int main() {
    	n = read();
    	m = read();
    	while (m--) {
    		o = read();
    		x = read();
    		if (o == 1) {
    			if (x) {
    				y = y ^ (1<<cnt);
    			}
    			cnt++;
    			if (cnt == n) cnt = 0;
    		} else {
    			if (cnt) write(((x>>(n-cnt))|((x&((1<<(n-cnt))-1))<<cnt))^y);
    			else write(x^y);
    			putchar(10);
    		}
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    6402
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者