您的位置:首页 > 其它

zoj2112

2015-08-26 10:36 309 查看
这道题是要求待修改的区间第k值,看的kuangbin的树状数组加主席树,这种方法是离线的。本来是想做hdu5412的,结果超时,所以只能交了zoj2110。没什么多说的,就是模板题。如果要求第k大,只要做相应的修改就行了,有多种修改的方法,只要能的出正确答案就行。

参考代码:http://www.cnblogs.com/kuangbin/p/3308118.html

(今天为了看书,没有吃包子,只吃了面包,本来想着反正有番茄酱,但是看到队友吃包子,还是各种口水流



2015.8.31:

回忆了一下模板。但是写时还是要注意细节。不过只要理解了原理,什么时候都能写,就是时间长短的问题。今天中午买了一个包子,结果划卡划多了,结果又多给了一个,吃的那叫一个痛哭流涕(因为菜太辣了!

)。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 50010
#define M 10010
#define Q 2600000

struct querynode{
int type;
int l;
int r;
int k;
};
int c[Q],lson[Q],rson[Q];
int T
,S
,use
;
int newid[2*N];
int num
;
bool usemark
;
querynode queryarray[M];
int n,m;
int tot;

void lisanhua(){
sort(newid+1,newid+m+1);
m=unique(newid+1,newid+m+1)-(newid+1);
}

int build(int l,int r){
int root=tot++;

c[root]=0;
if(l<r){
int middle=(l+r)>>1;

lson[root]=build(l,middle);
rson[root]=build(middle+1,r);
}
else{
lson[root]=-1;
rson[root]=-1;
}

return root;
}

int insert(int froroot,int anum,int cou){
int root=tot++,temproot=root;
int l=1,r=m;
c[root]=c[froroot]+cou;

while(l<r){
int middle=(l+r)>>1;

if(anum<=middle){
r=middle;
lson[temproot]=tot++;
rson[temproot]=rson[froroot];
temproot=lson[temproot];
froroot=lson[froroot];
}
else{
l=middle+1;
lson[temproot]=lson[froroot];
rson[temproot]=tot++;
temproot=rson[temproot];
froroot=rson[froroot];
}
c[temproot]=c[froroot]+cou;
}

return root;
}

int numhash(int x){
return lower_bound(newid+1,newid+m+1,x)-newid;
}

int lowbit(int x){
return (~x+1)&x;
}

void modify(int x,int anum,int cou){
while(x<=n){
S[x]=insert(S[x],anum,cou);
x=x+lowbit(x);
}
}

int sum(int x){
int ans=0;

while(x>0){
ans+=c[lson[use[x]]];
x=x-lowbit(x);
}

return ans;
}

int query(int left,int right,int k){
int l=1,r=m;
int tempr=T[right],templ=T[left-1];

for(int i=right;i>0;i=i-lowbit(i)){
use[i]=S[i];
}
for(int i=left-1;i>0;i=i-lowbit(i)){
use[i]=S[i];
}

while(l<r){
int middle=(l+r)>>1;
int cnt=sum(right)+c[lson[tempr]]-(sum(left-1)+c[lson[templ]]);

if(cnt>=k){
r=middle;
memset(usemark,false,sizeof(usemark));
for(int i=right;i>0;i=i-lowbit(i)){
use[i]=lson[use[i]];
usemark[i]=true;
}
for(int i=left-1;i>0;i=i-lowbit(i)){
if(!usemark[i]){
use[i]=lson[use[i]];
}
}
tempr=lson[tempr];
templ=lson[templ];
}
else{
l=middle+1;
memset(usemark,false,sizeof(usemark));
for(int i=right;i>0;i=i-lowbit(i)){
use[i]=rson[use[i]];
usemark[i]=true;
}
for(int i=left-1;i>0;i=i-lowbit(i)){
if(!usemark[i]){
use[i]=rson[use[i]];
}
}
tempr=rson[tempr];
templ=rson[templ];
k=k-cnt;
}
}

return l;
}

int main(){
int t;
int q;
char op[10];

scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&q);

for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
newid[i]=num[i];
}
m=n;
for(int i=0;i<q;i++){
scanf("%s",op);
if(op[0]=='Q'){
queryarray[i].type=0;
scanf("%d%d%d",&queryarray[i].l,&queryarray[i].r,&queryarray[i].k);
}
else{
queryarray[i].type=1;
scanf("%d%d",&queryarray[i].l,&queryarray[i].r);
newid[++m]=queryarray[i].r;
}
}

tot=0;
lisanhua();
T[0]=build(1,m);
for(int i=1;i<=n;i++){
T[i]=insert(T[i-1],numhash(num[i]),1);
}
for(int i=1;i<=n;i++){
S[i]=T[0];
}

for(int i=0;i<q;i++){
/*for(int i=1;i<=n;i++){
printf("%d ",num[i]);
}
printf("\n");*/

if(queryarray[i].type==0){
printf("%d\n",newid[query(queryarray[i].l,queryarray[i].r,queryarray[i].k)]);
}
else if(queryarray[i].type==1){
modify(queryarray[i].l,numhash(num[queryarray[i].l]),-1);
modify(queryarray[i].l,numhash(queryarray[i].r),1);
num[queryarray[i].l]=queryarray[i].r;
}
}
}

return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: