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;
}
参考代码: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;
}
相关文章推荐
- 链表排序问题
- 【算法导论】快速排序
- Highmaps网页图表教程之绘图区显示标签显示数据标签定位
- Qt 中显示中文
- 直方图规定化
- C++指针加整数、两个指针相减的问题
- EXPLAIN sql优化方法2 Using temporary ; Using filesort
- 修改arm开发板的IP地址
- 快速排序原理
- zoj2112
- PHP查询数据库中满足条件的记录条数(二种实现方法)
- ORA-00904: "STUDENTNUMBER": 标识符无效
- javascript--QUnit【javascript单元测试框架】
- HTTP头字段总结
- NOI系列赛中 C++容器使用总结
- contourArea函数
- HDU 1171 Big Event in HDU (由01背包演变的水题)
- UNIX网络编程0 IP头,TCP头,UDP头,MAC帧头定义
- app上传 需要的icon
- ecshop 分页