poj 3468 A Simple Problem with Integers

来源:互联网 发布:q宠大乐斗门派技能数据 编辑:程序博客网 时间:2024/06/05 15:13
A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072KTotal Submissions: 60604 Accepted: 18470Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915




线段树(更新线段,区间求和)

#include<stdio.h>#include<iostream>#include<algorithm>using namespace std; #define MAX_N 100001  __int64 sum = 0;  __int64 num[MAX_N];  struct node  {      int left;      int right;      __int64 count; //表示该节点的总个数      __int64 data;  //表示增量的那个数  }N[4*MAX_N];  void CreateTree(int i,int a,int b)  {      N[i].left = a;      N[i].right = b;      N[i].data = 0;      if(a == b)      {          N[i].count= num[a];return ;    }  int mid = (a+b)/2;  CreateTree(i*2,a,mid);  CreateTree(i*2+1,mid+1,b);  N[i].count= N[i*2].count+ N[i*2+1].count;  }  void insert(int i,int a,int b,int c)  {      if(N[i].left == a && N[i].right == b)      {          N[i].data += c;       return ;    }      int mid = (N[i].left + N[i].right) /2;  if(b <= mid)  insert(i*2,a,b,c);  else if(a > mid)  insert(i*2+1,a,b,c);  else  {  insert(i*2,a,mid,c);  insert(i*2+1,mid+1,b,c);  }  N[i].count = (N[i*2].count + (N[i*2].right - N[i*2].left + 1) * N[i*2].data)+(N[i*2+1].count + (N[i*2+1].right - N[i*2+1].left + 1) * N[i*2+1].data);  }  void find(int i,int a,int b)  {      if(N[i].left == a && N[i].right == b)      {          sum+= N[i].count + N[i].data*(b-a+1);      return ;    }  N[i*2].data += N[i].data;  N[i*2+1].data += N[i].data;  N[i].count += N[i].data * (N[i].right - N[i].left + 1);  N[i].data = 0; int mid = (N[i].left + N[i].right)/2;  if(b <= mid)  find(i*2,a,b);  else if(a > mid)  find(i*2+1,a,b);  else  {  find(i*2,a,mid);  find(i*2+1,mid+1,b);  }       }  int main()  {      int n,m,x1,x2,x3;      char c;      int i;      while(scanf("%d%d",&n,&m)!=EOF)      {          for(i=1;i<=n;i++)              scanf("%I64d",&num[i]);          CreateTree(1,1,n);          while(m--)          {              scanf("%*c%c",&c);              if(c == 'Q')              {                  sum = 0;                  scanf("%d%d",&x1,&x2);                  find(1,x1,x2);                  printf("%I64d\n",sum);              }              else               {                  scanf("%d%d%d",&x1,&x2,&x3);                  insert(1,x1,x2,x3);              }          }      }  return 0;}  


#include<stdio.h> #include<string.h> #define LL(a) a<<1 #define RR(a) (a<<1)+1 #define Mid(a,b) (a+b)>>1 const int N = 100010; struct nodes {     int l, r, mid;     __int64 sum, add; } node[5*N]; int n, m, num[N]; __int64 sum; void Build(int id, int l, int r) {      node[id].add = 0;      node[id].l = l;      node[id].r = r;      node[id].mid = (l + r) >> 1;     if(l == r)      {          node[id].sum = num[l];         return;      }      Build(LL(id), l, node[id].mid);      Build(RR(id), node[id].mid + 1, r);      node[id].sum = node[id<<1].sum + node[(id<<1)+1].sum; } void Add(int id, int l, int r, __int64 inc) {     if(node[id].l == l && node[id].r == r)      {         //到达满区间,修改增量即可,这样就不要将增量加直到叶子节点          node[id].add += inc;         return;      }      node[id].sum += (r - l + 1) * inc;     if(l > node[id].mid)          Add(RR(id), l, r, inc);     else if(r <= node[id].mid)          Add(LL(id), l, r, inc);     else      {          Add(LL(id), l, node[id].mid, inc);          Add(RR(id), node[id].mid + 1, r, inc);      } } void Getsum(int id, int l, int r) {     //如果某个节点有增量,计算节点本身的sum,将增量归还于子节点,同时本区间增量清0      if(node[id].add != 0)      {          node[id].sum += (node[id].r - node[id].l + 1) * node[id].add;          node[id<<1].add += node[id].add;          node[(id<<1)+1].add += node[id].add;          node[id].add = 0;      }     if(node[id].l == l && node[id].r == r)      {          sum = sum + node[id].sum;         return;      }     if(l > node[id].mid)          Getsum((id << 1) + 1, l, r);     else if(r <= node[id].mid)          Getsum(id << 1, l, r);     else      {          Getsum(id << 1, l, node[id].mid);          Getsum((id << 1) + 1, node[id].mid + 1, r);      } } int main() {     int i, a, b;     __int64 c;     char op[4];      freopen("d:\\1.txt", "r", stdin);     while(scanf("%d%d", &n, &m) != EOF)      {         for(i = 1; i <= n; i++)              scanf("%d", &num[i]);          Build(1, 1, n);         while(m--)          {              scanf("%s", op);             if(op[0] == 'Q')              {                  scanf("%d%d", &a, &b);                  sum = 0;                  Getsum(1, a, b);                  printf("%I64d\n", sum);              }             else              {                  scanf("%d%d%I64d", &a, &b, &c);                  Add(1, a, b, c);              }          }      }     return 0; } 



TML代码:
真心苦逼啊。。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int max(int a,int b){    return (a>b?a:b);}int a[200000];struct Node{    int left,right;    int t;}node[4*200000];void MakeTree(int l,int r,int i){  node[i].left=l;  node[i].right=r;   if(l==r)   {       node[i].t=a[l];       return ;   }  int mid=(l+r)/2;  MakeTree(l,mid,2*i);  MakeTree(mid+1,r,2*i+1);  node[i].t=node[2*i].t+node[2*i+1].t;}void UpdateTree(int i,int x,int k){    int l=node[i].left;    int r=node[i].right;    int mid=(l+r)/2;    if(x==l&&x==r)    {        node[i].t+=k;        return ;    }    if(x>mid)        UpdateTree(2*i+1,x,k);    else        UpdateTree(2*i,x,k);    node[i].t=node[2*i].t+node[2*i+1].t;}int QueryTree(int x,int y,int i){    if(node[i].left==x && node[i].right==y)        return node[i].t;    int m=(node[i].left+node[i].right)/2;    if(x>m)        return QueryTree(x,y,2*i+1);    else if(y<=m)        return QueryTree(x,y,2*i);    else        return QueryTree(x,m,2*i)+QueryTree(m+1,y,2*i+1);}int main (){    int T,n,m;    int i,j,x,y,k;    char c[10];    while(~scanf("%d%d",&n,&m))    {        for(i=1;i<=n;i++)            scanf("%d",&a[i]);        MakeTree(1,n,1);        for(j=1;j<=m;j++)        {         scanf("%s%d%d",c,&x,&y);         if(c[0]=='C')         {             scanf("%d",&k);             for(i=x;i<=y;i++)             {                 UpdateTree(1,i,k);             }         }         else            cout<<QueryTree(x,y,1)<<endl;       }    }    return 0;}





0 0
原创粉丝点击