B是一个看起来很KDT的题  但是因为KDT是n^1.5的所以t  而且因为KDT需要周期性的重建所以复杂度会更高

因为只有51种颜色 所以想当然的就去想了状态压缩 因为询问的区间范围 x一定是从1开始的 所以可以用cdq分治

用cdq分治去掉时间维度 按x排序 用线段树维护每个区间的状态(压缩颜色) 单点更新和区间查询

因为每次线段树做cdq的一部分之后 我们都要去除影响 但是不能rebuild

1 可以用一个last代表这个区间上一次使用线段树是什么时候 每次更新和查询的时候对他进行更新

2 也可以写一个clean函数 在线段树使用结束之后 对单点更新所有经过的状态置0

3 可以单点更新 更新到叶子节点的时候将其置为0 然后递归回来 zt[ro] = zt[lson] | zt[rson]  和第二个差不多

第一个可以省去一个常数

但是其实不用cdq 因为相对还是麻烦一点

可以暴力的建立51个线段树枚举每个颜色 每个区间维护l r 区间内该颜色的最低x是多少 也是利用了查询是从1开始的特性

cdq 使用last

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<string>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
#define lro ro*2
#define rro ro*2+1
#define L long long
#define pb push_back
#define lala printf("--------\n");
#define ph push
#define rep(i, a, b) for (L i=a;i<=b;++i)
#define dow(i, b, a) for (L i=b;i>=a;--i)
#define fmt(i,n) if(i==n)printf("\n");else printf(" ") ;
#define fi first
#define se second
template<class T> inline void flc(T &A, L x){memset(A, x, sizeof(A));}
L read(){L x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} struct node {
L x,y,c;
L y2;
L xw ;
L time ;
node(L xx,L yy,L cc,L y22,L ww,L tt) : x(xx) , y (yy) , c(cc) , y2(y22) , xw(ww) , time(tt) {}
node() {}
};
L ans[300050] ;
vector<node>q1 , q2 ;
L tot ; struct tre {
L last ;
L zt ;
}t[1000050 * 6];
void build(L ro , L l , L r) {
t[ro].zt = 0 ;
if(l == r) return ;
L mid = (l + r) >> 1 ;
build(lro , l , mid) ; build(rro , mid+1 , r) ;
}
void upda(L ro , L l , L r , L id , L val , L pos) {
if(t[ro].last != id) {
t[ro].last = id ;
t[ro].zt = 0 ;
}
t[ro].zt |= (1LL << val) ;
L mid = (l + r) >> 1 ;
if(l == r) return ;
if(pos <= mid) upda(lro , l , mid , id , val , pos) ;
else upda(rro , mid+1 , r , id , val , pos) ;
}
void query(L ro, L l , L r , L id , L ql , L qr , L ansid) {
if(t[ro].last != id) return ;
if(l >= ql && r <= qr) {
ans[ansid] |= t[ro].zt ;
return ;
}
if(l == r) return ;
L mid = (l + r) >> 1 ;
if(ql <= mid) query(lro , l , mid , id , ql , qr , ansid) ;
if(qr > mid) query(rro , mid+1 , r , id, ql , qr , ansid) ;
} void cdq2(L LL , L RR) {
tot ++ ;
rep(i , LL , RR) {
if(q2[i].xw == 0) {
upda(1,1,1000000,tot,q2[i].c,q2[i].y) ;
}
else {
query(1,1,1000000,tot,q2[i].y,q2[i].y2,q2[i].time) ;
}
}
} bool cmp(node a,node b) {
if(a.x==b.x) return a.time < b.time ;
return a.x < b.x ;
}
void cdq(L LL , L RR) {
if(RR <= LL) return ;
L M = (LL + RR) >> 1 ;
cdq(LL,M) ;
q2.clear();
rep(i,LL,M) {
if(q1[i].xw == 0) q2.pb(q1[i]) ;
}
rep(i,M+1,RR) {
if(q1[i].xw == 1) q2.pb(q1[i]) ;
}
sort(q2.begin(),q2.end(),cmp) ;
int siz = q2.size() ;
cdq2(0,siz-1);
cdq(M+1,RR) ;
} L zh(L x) {
L res = 0 ;
while(x) {
if(x&1) res ++ ;
x>>=1 ;
}
return res ;
} int main () {
tot = 0 ;
// freopen("6183.txt" , "r" , stdin) ;
L op ;
q1.clear() ;
while(scanf("%lld" , &op) != EOF) {
if(op == 0) {
build(1,1,1000000) ;
int siz = q1.size() ;
cdq(0,siz-1);
for(L i=0;i<siz;i++ ){
if(ans[i] >= 0) printf("%lld\n" , zh(ans[i])) ;
}
q1.clear();
flc(ans,0) ;
}
else if(op == 3) {
build(1,1,1000000) ;
int siz = q1.size() ;
cdq(0,siz-1);
for(L i=0;i<siz;i++ ){
if(ans[i] >= 0) printf("%lld\n" , zh(ans[i])) ;
}
q1.clear();
flc(ans,0) ;
return 0;
}
else if(op == 1) {
L x=read() ;
L y=read() ;
L c=read() ;
int siz = q1.size() ;
ans[siz] = -1 ;
q1.pb(node(x,y,c,0,0,siz)) ;
}
else if(op == 2) {
L x=read() ;
L y=read() ;
L y2=read() ;
int siz = q1.size() ;
q1.pb(node(x,y,0,y2,1,siz)) ;
}
}
}

cdq 使用clean

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<string>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
#define lro ro*2
#define rro ro*2+1
#define L long long
#define pb push_back
#define lala printf("--------\n");
#define ph push
#define rep(i, a, b) for (L i=a;i<=b;++i)
#define dow(i, b, a) for (L i=b;i>=a;--i)
#define fmt(i,n) if(i==n)printf("\n");else printf(" ") ;
#define fi first
#define se second
template<class T> inline void flc(T &A, L x){memset(A, x, sizeof(A));}
L read(){L x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} struct node {
L x,y,c;
L y2;
L xw ;
L time ;
node(L xx,L yy,L cc,L y22,L ww,L tt) : x(xx) , y (yy) , c(cc) , y2(y22) , xw(ww) , time(tt) {}
node() {}
};
L ans[300050 * 2] ;
vector<node>q1 , q2 ; L zt[1000050 * 10] ;
void build(L ro , L l , L r) {
zt[ro] = 0 ;
if(l == r) return ;
L mid = (l + r) >> 1 ;
build(lro , l , mid) ; build(rro , mid+1 , r) ;
}
void upda(L ro , L l , L r , L val , L pos) {
zt[ro] |= (1LL << val) ;
if(l == r) return ;
L mid = (l + r) >> 1 ;
if(pos <= mid) upda(lro , l , mid , val , pos) ;
else upda(rro , mid+1 , r , val , pos) ;
}
void query(L ro, L l , L r , L ql , L qr , L ansid) {
if(l >= ql && r <= qr) {
ans[ansid] |= zt[ro] ;
return ;
}
if(l == r) return ;
L mid = (l + r) >> 1 ;
if(ql <= mid) query(lro , l , mid , ql , qr , ansid) ;
if(qr > mid) query(rro , mid+1 , r , ql , qr , ansid) ;
}
void clean(L ro , L l , L r , L pos) {
zt[ro] = 0 ;
if(l == r) return ;
L mid = (l + r) >> 1 ;
if(pos <= mid) clean(lro , l , mid , pos) ;
else clean(rro , mid+1 , r , pos) ;
} void cdq2(L LL , L RR) {
rep(i , LL , RR) {
if(q2[i].xw == 0) {
upda(1,1,1000000,q2[i].c,q2[i].y) ;
}
else {
query(1,1,1000000,q2[i].y,q2[i].y2,q2[i].time) ;
}
}
rep(i , LL , RR) {
if(q2[i].xw == 0) {
clean(1,1,1000000,q2[i].y) ;
}
}
} bool cmp(node a,node b) {
if(a.x==b.x) return a.time < b.time ;
return a.x < b.x ;
}
void cdq(L LL , L RR) {
if(RR <= LL) return ;
L M = (LL + RR) >> 1 ;
cdq(LL,M) ;
q2.clear();
rep(i,LL,M) {
if(q1[i].xw == 0) q2.pb(q1[i]) ;
}
rep(i,M+1,RR) {
if(q1[i].xw == 1) q2.pb(q1[i]) ;
}
sort(q2.begin(),q2.end(),cmp) ;
L siz = q2.size() ;
cdq2(0,siz-1);
cdq(M+1,RR) ;
} L zh(L x) {
L res = 0 ;
while(x) {
if(x%2 == 1) res ++ ;
x /= 2 ;
}
return res ;
} int is[300050] ; int main () {
//freopen("6183.txt" , "r" , stdin) ;
L op ;
flc(ans , 0) ;
q1.clear() ;
while(scanf("%lld" , &op) != EOF) {
if(op == 0) {
build(1,1,1000000) ;
L siz = q1.size() ;
cdq(0,siz-1);
for(L i=0;i<siz;i++ ){
if(is[i]) printf("%lld\n" , zh(ans[i])) ;
}
q1.clear();
flc(ans,0) ;
}
else if(op == 3) {
build(1,1,1000000) ;
L siz = q1.size() ;
cdq(0,siz-1);
for(L i=0;i<siz;i++ ){
if(is[i]) printf("%lld\n" , zh(ans[i])) ;
}
q1.clear();
flc(ans,0) ;
return 0;
}
else if(op == 1) {
L x=read() ;
L y=read() ;
L c=read() ;
L siz = q1.size() ;
ans[siz] = -32000 ;
is[siz] = 0 ;
q1.pb(node(x,y,c,0,0,siz)) ;
}
else if(op == 2) {
L x=read() ;
L y=read() ;
L y2=read() ;
L siz = q1.size() ;
ans[siz] = 0 ;
is[siz] = 1 ;
q1.pb(node(x,y,0,y2,1,siz)) ;
}
}
}

51个线段树 需要动态的建点 用到哪个点再去建它 省空间

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
#define L long long
#define pb push_back
#define ph push
#define lala printf(" --------- \n") ;
#define rep(i, a, b) for (int i=a;i<=b;++i)
#define dow(i, b, a) for (int i=b;i>=a;--i)
#define fmt(i,n) if(i==n)printf("\n");else printf(" ") ;
#define lro ro*2
#define rro ro*2+1
#define fi first
#define se second
template<class T> inline void flc(T &A, int x){memset(A, x, sizeof(A));}
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} int op ;
int ls[50 * 500000 * 4] ;
int rs[50 * 500000 * 4] ;
int mi[50 * 500000 * 4] ;
int root[70] ;
int cnt ; void init() {
rep(i,0,cnt) {
root[i] = ls[i] = rs[i] = 0 ;
}
cnt = 0 ;
}
void upda(int & x , int l , int r , int pos , int val) {
if(x == 0) {
x = ++cnt ;
mi[x] = 10000000 ;
}
mi[x] = min(mi[x] , val) ;
if(l == r) return ;
int mid = (l + r) / 2 ;
if(pos <= mid) {
upda(ls[x] , l , mid , pos , val) ;
}
else {
upda(rs[x] , mid+1 , r , pos , val) ;
}
}
int ok ;
void query(int x , int l , int r , int ql , int qr , int fz) {
if(ok || x == 0) return ;
if(ql <= l && qr >= r) {
if(mi[x] <= fz) ok = 1 ;
return ;
}
int mid = (l + r) / 2 ;
if(ql <= mid) query(ls[x] , l , mid , ql , qr , fz) ;
if(qr > mid) query(rs[x] , mid+1 , r , ql , qr , fz) ;
} int main () {
while(scanf("%d" , &op) != EOF){
if(op == 3) return 0 ;
if(op == 0) {
init() ;
}
if(op == 1) {
int x = read() ; int y = read() ; int c = read() ;
upda(root[c] , 1 , 1000000 , y , x) ;
}
if(op == 2) {
int x = read() ;
int y1 = read() ; int y2 = read() ;
int ans = 0 ;
rep(i,0,50) {
ok = 0 ;
query(root[i] , 1 , 1000000 , y1 , y2 , x) ;
if(ok) ans ++ ;
}
printf("%d\n" , ans) ;
}
}
}

K的xor让人一看就觉得是字典树 但是正常肯定没法做 想到类似主席树一样 用dfs序把每个子树分成区间 就可以写出一个挺像主席树的可持久化字典树了

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
#define L long long
#define pb push_back
#define ph push
#define lala printf(" --------- \n") ;
#define rep(i, a, b) for (L i=a;i<=b;++i)
#define dow(i, b, a) for (L i=b;i>=a;--i)
#define fmt(i,n) if(i==n)printf("\n");else printf(" ") ;
#define lro ro*2
#define rro ro*2+1
#define fi first
#define se second
template<class T> inline void flc(T &A, L x){memset(A, x, sizeof(A));}
L read(){L x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} struct node {
L l , r , sum ;
}b[5000050];
node newnode() {
node a;
a.l = a.r = -1 ;
a.sum = 0 ;
return a ;
}
L n , q ;
L a[100050] ; L root[100050] ; struct ed {
L v , nex ;
}bb[200050] ;
L head[100050] ;
L cnt ;
void add(L u,L v) {
cnt ++ ;
bb[cnt].v=v;bb[cnt].nex=head[u];head[u]=cnt;
}
L l[100050] ;
L r[100050] ;
L num ;
L p[100050] ;
void dfs(L u , L fa) {
num ++ ;
l[u] = num ;
p[num] = u ;
for(L i = head[u] ; i != -1 ; i = bb[i].nex) {
L v = bb[i].v ;
if(v == fa) continue ;
dfs(v,u) ;
}
r[u] = num ;
}
L tot ; L c[35] ;
void fj(L x) {
rep(i,1,33) {
c[i] = x % 2 ;
x /= 2 ;
}
} void inse1(L w , L val ) {
fj(w) ;
L ro = 0 ;
dow(i,33,1) {
if(c[i] == 1) {
if(b[ro].r == -1) {
b[ro].r = ++cnt ;
b[cnt] = newnode() ;
}
ro = b[ro].r ;
b[ro].sum += val ;
}
else {
if(b[ro].l == -1) {
b[ro].l = ++cnt ;
b[cnt] = newnode() ;
}
ro = b[ro].l ;
b[ro].sum += val ;
}
}
} void inse(L w , L id , L y) {
fj(w) ;
tot ++ ;
root[id] = tot ;
L ro = tot ;
b[ro] = b[y] ;
b[ro].sum ++ ;
dow(i,33,1) {
if(c[i] == 1) {
b[ro].r = ++cnt ;
ro = b[ro].r ;
y = b[y].r ;
b[ro] = b[y] ;
b[ro].sum ++ ;
}
else{
b[ro].l = ++cnt ;
ro = b[ro].l ;
y = b[y].l ;
b[ro] = b[y] ;
b[ro].sum ++ ;
}
}
}
L sd[50] ;
L query(L l , L r , L x) {
fj(x) ;
L res = 0 ;
L rol = root[l-1] ;
L ror = root[r] ;
dow(i,33,1) {
if(c[i] == 1) {
if(b[b[ror].l].sum - b[b[rol].l].sum > 0) {
rol = b[rol].l ;
ror = b[ror].l ;
res += sd[i] ;
}
else {
rol = b[rol].r ;
ror = b[ror].r ;
}
}
else {
if(b[b[ror].r].sum - b[b[rol].r].sum > 0) {
rol = b[rol].r ;
ror = b[ror].r ;
res += sd[i] ;
}
else {
rol = b[rol].l ;
ror = b[ror].l ;
}
}
}
return res ;
}
int main () {
sd[1] = 1LL ;
rep(i , 2 , 33) {
sd[i] = sd[i-1] * 2LL ;
}
while(scanf("%lld" , &n) != EOF) {
flc(head,-1);
cnt = 0 ;
b[0] = newnode() ;
root[0] = 0 ;
tot = 0 ;
q = read() ;
rep(i,1,n) {
a[i]=read();
}
rep(i,2,n) {
L fa=read();
add(fa,i) ;
add(i,fa) ;
}
num = 0 ;
dfs(1 , -1) ;
rep(i,1,n) {
inse1(a[i] , 1) ;
inse1(a[i] , -1) ;
}
rep(i,1,n) {
inse(a[p[i]] , i , root[i-1]) ;
}
while(q -- ) {
L u , x ;
u = read();
x = read();
L ans = query(l[u] , r[u] , x) ;
printf("%lld\n" , ans) ;
}
}
}

广西邀请赛 B+K的更多相关文章

  1. 2017 ICPC 广西邀请赛1004 Covering

    Covering Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  2. 2017 ICPC 广西邀请赛1005 CS Course

    CS Course Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  3. 2017ICPC/广西邀请赛1005(水)HDU6186

    CS Course Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  4. 2017ICPC/广西邀请赛1001(水)HDU6181

    A Math Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. 2017ACM/ICPC广西邀请赛-重现赛 1004.Covering

    Problem Description Bob's school has a big playground, boys and girls always play games here after s ...

  6. 2017ACM/ICPC广西邀请赛-重现赛

    HDU 6188 Duizi and Shunzi 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6188 思路: 签到题,以前写的. 实现代码: #inc ...

  7. 2017ACM/ICPC广西邀请赛-重现赛 1001 A Math Problem

    2017-08-31 16:48:00 writer:pprp 这个题比较容易,我用的是快速幂 写了一次就过了 题目如下: A Math Problem Time Limit: 2000/1000 M ...

  8. 2017ACM/ICPC广西邀请赛-重现赛1005 CS course

    2017-08-31 16:19:30 writer:pprp 这道题快要卡死我了,队友已经告诉我思路了,但是做题速度很缓慢,很费力,想必是因为之前 的训练都是面向题解编程的缘故吧,以后不能这样了,另 ...

  9. 2017ACM/ICPC广西邀请赛-重现赛(感谢广西大学)

    上一场CF打到心态爆炸,这几天也没啥想干的 A Math Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

随机推荐

  1. NoSQL-redis with python

    首先,先去看了一下NoSQL的概念: Wiki中参考的NoSQL终极指南(nosql-database.org)中说: NoSQL DEFINITION: Next Generation Databa ...

  2. 160818、CSS页面布局笔记

    居中布局   水平居中 父元素和子元素的宽度都未知 inline-block + text-ailgn .child{display:inline-block;} .parent{text-align ...

  3. You can add an index on a column that can have NULL values if you are using the MyISAM, InnoDB, or MEMORY storage engine.

    w https://dev.mysql.com/doc/refman/5.7/en/create-index.html MySQL :: MySQL 5.7 Reference Manual :: B ...

  4. PowerPC架构与X86架构

    PowerPC架构 PowerPC是一种精简指令集(RISC)架构的中央处理器(CPU),其基本的设计源自IBM(国际商用机器公司)的POWER(Performance Optimized With ...

  5. qt sql 模块有哪些类?

    Class Description translate.google QSqlDatabase Handles a connection to a database 处理与数据库的连接 QSqlDri ...

  6. Datetime 模块求日期差

    Datetime 模块求日期差 导入 datetime 模块/实例化当前时间对象 调用.date() 方法 得到当前年/月/日时间 实例化时间差对象 delta 求当前日期减去时间差 delta 后的 ...

  7. Python的模块与函数以及与自动化的结合

    3 模块与函数 3.1程序结构 python的程序由package,module,function组成,分别是包,模块,函数.模块是函数和类的集合,包,模块,函数之间的关系如下: 3.2模块 pyth ...

  8. 【zabbix】zabbix忘记密码,重置密码

    忘记密码这种事经常会发生,这里我们介绍一种zabbix忘记用户密码的处理方式. 原理: zabbix存储在数据库中用户名密码是经过32位,小写,md5加密过的.我们可以手动修改数据库中用户的密码. 实 ...

  9. Log level with log4j and Spark

    Log Level Usages OFF This is the most specific, which allows no logging at all FATAL This is the mos ...

  10. PAT 天梯赛 L1-033. 出生年 【水】

    题目链接 https://www.patest.cn/contests/gplt/L1-033 AC代码 #include <cstdio> #include <cstring> ...