NOI十连测 第五测 T2

思路:考虑建立可持久化线段树,第一层维护的是i这个位置的next位置,第二层,维护的是接下来走这个字符会到哪个节点。

感觉很巧妙啊,不愧是Claris

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 int v[18000005],l[18000005],r[18000005],sz;
 7 int d[300005],root[300005];
 8 int read(){
 9     int t=0,f=1;char ch=getchar();
10     while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-1;ch=getchar();}
11     while (‘0‘<=ch&&ch<=‘9‘){t=t*10+ch-‘0‘;ch=getchar();}
12     return t*f;
13 }
14 int modify(int k,int L,int R,int pos,int vv){
15     int kk=++sz;
16     if (L==R){
17         v[kk]=vv;
18         return kk;
19     }
20     int mid=(L+R)>>1;
21     if (pos<=mid) l[kk]=modify(l[k],L,mid,pos,vv),r[kk]=r[k];
22     else r[kk]=modify(r[k],mid+1,R,pos,vv),l[kk]=l[k];
23     return kk;
24 }
25 int ask(int k,int L,int R,int pos){
26     if (L==R){
27         return v[k];
28     }
29     int mid=(L+R)>>1;
30     if (pos<=mid) return ask(l[k],L,mid,pos);
31     else return ask(r[k],mid+1,R,pos);
32 }
33 int main(){
34     int n=read(),m=read(),type=read(),ans=0;
35     for (int i=1;i<=n;i++){
36         int x=read(),y=read();
37         if (type) x^=ans,y^=ans;
38         d[i]=d[x]+1;
39         int z=ask(root[x],0,n,x);
40         int next=ask(z,1,m,y);
41         printf("%d\n",ans=d[i]-d[next]);
42         root[i]=modify(root[x],0,n,x,modify(z,1,m,y,i));
43         root[i]=modify(root[i],0,n,i,ask(root[i],0,n,next));
44     }
45 }
时间: 2024-12-22 05:06:02

NOI十连测 第五测 T2的相关文章

NOI十连测 第五测 T3

思路:考试的时候我非常地**,写了圆并,然后还TM写了半平面交和三角剖分,虽然只有30分..但是看在我写了500行的份上还是挂着吧.. 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 const double Pi=acos(-1); 7 const double eps=1e-10; 8 i

NOI十连测 第五测 T1

1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 int f[257][257],n,type,V[257],g[257][257],ans,cnt; 7 char op[204]; 8 int read(){ 9 int t=0,f=1;char ch=getchar(); 10 while

BZOJ NOI十连测 第一测 T2

思路:看到这题,就感觉是一道很熟悉的题目: http://www.cnblogs.com/qzqzgfy/p/5535821.html 只不过这题的K最多可以到N,而且边权不再只是1,考试的时候yy了一下做法: 找k次直径,第一次把边取反,要是第二次再取到同样的边,那就把它变成0,毕竟每条边只经过2次嘛,YY的很好,实际上,交上去,5分TAT 后来听以为神犇说不是取0,而是继续取反,每条边取一次就取反一次,woc.. 1 #include<cstdio> 2 #include<cmath

BZOJ NOI十连测 第二测 T2

思路:20%可以搜索.. 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #include<time.h> 7 #define ll long long 8 const ll Mod=998244353; 9 ll jc[300005],jcny[300005]; 10 int n

NOI十连测 第四测 T3

思路: 算法一:可以n^2找出每个点的权值,然后n^2做完,预计得分10 算法二:随机找点然后每次找最高..貌似只有10分?然而考试的时候煞笔了,边界设成inf.. 算法三:随机找几个点,然后随机爬山,听说有50~70 算法四:考虑将列分治,每次分成2部分,找出每部分边界的最大值,判断最大值左边和右边的大小,然后往大的那一边递归,预计得分70 算法五:不仅将列分治,并且将行分治,将一个n*n的矩阵划分,然后递归找,预计得分100 1 #include<bits/stdc++.h> 2 #inc

Noi 十连测 基因改造计划

SOL: 我们跑马拉车算法,然后写主席树维护. #include<bits/stdc++.h> #define LL long long #define M 6000007 #define N 260010 #define Mid (l+r>>1) using namespace std; LL allsf,allsi,allcnt; int n,m; #define sight(c) ('0'<=c&&c<='9') inline void read(

[NOI十连测] 二进制的世界

题意 给定一个长度为 n 的序列 A , 以及一种位运算 Op . 对于每个位置 x , 求 $\min_{y < x} A[y] ~ Op ~ A[x]$ . n <= 100000, 0 <= A[i] <= 65536 . 一个高效的Trick 我们可以贪心地尽可能使高的位大. g[x] 表示前 8 位为 x 的一个 vector . 我们维护 g 进行剪枝. 1 #include <cstdio> 2 #include <cstring> 3 #in

NOI十连测 第四测 T1

思路:首先每个蚂蚁移速相同,而且碰到就转头,这其实等价于擦肩而过! 看到2n个数互不相同就觉得方便多了:枚举每个数字往左或者往右作为最慢,然后考虑其他蚂蚁有多少种走路方向. (1),走的距离大于m/2 假如红色描述的是一个蚂蚁的移动轨迹,那么蓝色部分左边的蚂蚁只能向左走,蓝色右边的蚂蚁只能向右走. 而蓝色部分中的蚂蚁可以向左也可以向右,方案数为2^n,n为蓝色部分蚂蚁数量. (2),走的距离小于m/2 如图,则蓝色部分左边的蚂蚁只能向左,蓝色部分右边的蚂蚁只能向右.而蓝色部分中间不能有蚂蚁!,这

NOI十连测 DAY3 T1

这么二逼的题考试的时候我想了好久,我真是太弱了... 首先,由于ans都乘上了i*(i-1)/2,实际上要求的就是每个数的所有可能出现次数*这个数的权值. 我们发现,每个数的本质是一样的,我们记一个sum为数的总和,这样只要统计一次就OK了. 我们把每次的选择抽象成有向边,每个状态视为点,这样就构成一个有根树. 如图 我们只考虑1对答案的贡献.如图,在每层计算当前合并对答案的贡献,也就是要能得知我在这个节点选择合并1或者1的联通块,那么我能覆盖到几个叶子节点? 那么就变成O(n)的组合数学题了.