提交57.19k
通过30.25k
时间限制1.00s
展开
如题,已知一个数列,你需要进行下面两种操作:
将某区间每一个数数加上 xx;
求出某一个数的值。
第一行包含两个整数 NN、MM,分别表示该数列数字的个数和操作的总个数。
第二行包含 NN 个用空格分隔的整数,其中第 ii 个数字表示数列第 ii 项的初始值。
接下来 MM 行每行包含 22 或 44个整数,表示一个操作,具体如下:
操作 11: 格式:1 x y k
含义:将区间 [x,y][x,y] 内每个数加上 kk;
操作 22: 格式:2 x
含义:输出第 xx 个数的值。
输出包含若干行整数,即为所有操作 22 的结果。
输入 #1复制
5 5 1 5 4 2 3 1 2 4 2 2 3 1 1 5 -1 1 3 5 7 2 4
输出 #1复制
6 10
样例 1 解释:
故输出结果为 6、10。
数据规模与约定
对于 30%30% 的数据:N≤8,M≤10N≤8,M≤10;
对于 70%70% 的数据:N≤10000,M≤10000N≤10000,M≤10000;
对于 100%100% 的数据:1≤N,M≤5000001≤N,M≤500000,1≤x,y≤n1≤x,y≤n,保证任意时刻序列中任意元素的绝对值都不大于 230230。
/* *@Author: GuoJinlong *@Language: C++ */ //#include <bits/stdc++.h> #include<iostream> #include<cstdio> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<list> #include<set> #include<iomanip> #include<cstring> #include<cctype> #include<cmath> #include<cstdlib> #include<ctime> #include<cassert> #include<sstream> #include<algorithm> using namespace std; const int mod=1e9+7; typedef long long ll; #define ls (p<<1) #define rs (p<<1|1) #define mid (l+r)/2 #define over(i,s,t) for(register long long i=s;i<=t;++i) #define lver(i,t,s) for(register long long i=t;i>=s;--i) const int MAXN = 305; const int INF = 0x3f3f3f3f; const int N=5e4+7; const int maxn=1e5+5; const double EPS=1e-10; const double Pi=3.1415926535897; //inline double max(double a,double b){ // return a>b?a:b; //} //inline double min(double a,double b){ // return a<b?a:b; //} int xd[8] = {0, 1, 0, -1, 1, 1, -1, -1}; int yd[8] = {1, 0, -1, 0, -1, 1, -1, 1}; //void Fire(){ // queue<node> p; // p.push({fx,fy,0}); // memset(fire, -1, sizeof(fire)); // fire[fx][fy]=0; // while(!p.empty()){ // node temp=p.front(); // p.pop(); // for(int i=0;i<8;i++){ // int x=temp.x+xd[i]; // int y=temp.y+yd[i]; // if(x<0||x>=n||y<0||y>=m||fire[x][y]!=-1){ // continue; // } // fire[x][y]=temp.val+1; // p.push({x,y,temp.val+1}); // } // } //} //int bfs(){ // queue<node> p; // memset(vis, 0, sizeof(vis)); // p.push({sx,sy,0}); // while (!p.empty()) { // node temp=p.front(); // vis[temp.x][temp.y]=1; // p.pop(); // for(int i=0;i<4;i++){ // int x=temp.x+xd[i]; // int y=temp.y+yd[i]; // if(x<0||x>=n||y<0||y>=m) continue; // if(x==ex&&y==ey&&temp.val+1<=fire[x][y]) return temp.val+1; // if(vis[x][y]||temp.val+1>=fire[x][y]||a[x][y]=='#') continue; // p.push({x,y,temp.val+1}); // } // } // return -1; //} //一维哈希 //int n; //string s; //int bas=131; //typedef unsigned long long ull; //const ull mod1=100001651; //ull a[100010]; //ull Hash(string s){ // ll ans=0; // for(int i=0;i<s.size();i++){ // ans*=bas; // ans+=int(s[i]); // ans%=mod1; // } // return ans; //} //二维哈希 //using lom=unsigned long long ; //const lom bas1=131,bas2=233; //const int M=505; //int n,m; //char a[M][M]; //lom _hash[M][M]; //lom p1[M],p2[M]; // // //void init(){ // p1[0]=1; // p2[0]=1; // for(int i=1;i<=505;i++){ // p1[i]=p1[i-1]*bas1; // p2[i]=p2[i-1]*bas2; // // } //} //void Hash(){ // _hash[0][0]=_hash[0][1]=_hash[1][0]=0; // for(int i=1;i<=n;i++){ //前缀和 // for(int j=1;j<=m;j++){ // _hash[i][j]=_hash[i][j-1]*bas1+a[i][j]-'a'; // } // } // for(int i=1;i<=n;i++){ //二维前缀和 // for(int j=1;j<=m;j++){ // _hash[i][j]+=_hash[i-1][j]*bas2; // } // } // //} //int pre[1010]; //int in[1010]; //int post[1010]; //int k; //struct node{ // int value; // node *l,*r; // node (int value=0,node *l=NULL,node *r=NULL):value(value),l(l),r(r){} //}; //void builttree(int l,int r,int &t,node * &root){ // int flag=-1; // for(int i=l;i<=r;i++){ // if(in[i]==pre[t]){ // flag=i; // break; // } // } // if(flag==-1) return; // root=new node(in[flag]); // t++; // if(flag>l) builttree(l,flag-1,t,root->l); // if(flag<r) builttree(flag+1,r,t,root->r); // //} //void preorder(node *root){ // if(root!=NULL) // { // post[k++]=root->value; // preorder(root->l); // preorder(root->r); // // } //} //void inorder(node *root){ // if(root!=NULL) // { // inorder(root->l); // post[k++]=root->value; // inorder(root->r); // // } //} //void postorder(node *root){ // if(root!=NULL) // { // postorder(root->l); // postorder(root->r); // post[k++]=root->value; // } //} int n,m; ll num[10000010]; int lowbit(int t) //lowbit()函数用来取一个二进制最低位的一与后边的0组成的数 { return t&(-t); } ll getsum(int x){ //求和 ll sum=0; while (x) { sum+=num[x]; x-=lowbit(x); } return sum; } void data(int x,int k){ //维护差分数组 while (x<=n) { num[x]+=k; x+=lowbit(x); } } int main(){ cin>>n>>m; int t=0; int x; for(int i=1;i<=n;i++){ cin>>x; data(i,x-t); t=x; } while (m--) { cin>>x; if(x==1){ int l,r,y; cin>>l>>r>>y; //l位和r+1位变 data(l,y); data(r+1,-y); } else{ cin>>x; cout<<getsum(x)<<endl; } } return 0; }