08:Challenge 1

总时间限制: 
10000ms
 
单个测试点时间限制: 
1000ms
 
内存限制: 
262144kB
描述

给一个长为N的数列,有M次操作,每次操作是以下两种之一:

(1)修改数列中的一个数

(2)求数列中某位置在某次操作后的值

输入
第一行两个正整数N和M。
第二行N个整数表示这个数列。
接下来M行,每行开头是一个字符,若该字符为'M',则表示一个修改操作,接下来两个整数x和y,表示把x位置的值修改为y;若该字符为'Q',则表示一个询问操作,接下来两个整数x和y,表示求x位置在第y次操作后的值。
输出
对每一个询问操作单独输出一行,表示答案。
样例输入
5 3
1 2 3 4 5
Q 1 0
M 1 3
Q 1 2
样例输出
1
3
提示
1<=N<=10^5,1<=M<=10^5,输入保证合法,且所有整数可用带符号32位整型存储。

很多人第一眼看到这道题觉得要用主席树什么的了。

但是。

rope大法好!!。

没什么好解释的,就是个裸地不能再裸地模板题,,,

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int MAXN=2000050;
const int maxn=0x7fffffff;
void read(int &n)
{
    char c='+';int x=0;bool flag=0;
    while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
    while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
    flag==1?n=-x:n=x;
}

rope<int> *rp[MAXN];
int a[MAXN];
int tot=0;
int main()
{
	ios::sync_with_stdio(0);
    int n,m;
    read(n);read(m);
    for(int i=1;i<=n;i++)
    	read(a[i]);
    rp[0]=new rope<int>(a+1,a+n+1);
    for(int i=1;i<=m;i++)
    {
    	rp[i]=new rope<int>(*rp[i-1]);
    	char c=getchar();
		int x,y;
    	if(c=='Q')
    	{
    		int l,r;
    		int ans=0;
    		read(l);read(r);read(x);
    		for(int i=l;i<=r;i++)
    			ans+=(rp[x]->at(i-1));
    		printf("%d\n",ans);
		}
		else
		{
			read(x);read(y);
			rp[i]->replace(x-1,y);
		}
	}
    return 0;
}

 

  

 

posted @ 2017-08-09 20:35  自为风月马前卒  阅读(382)  评论(0编辑  收藏  举报

Contact with me