区间修改点查询 HDU1556

  1 #include <iostream>
  2 #include <cstdio>
  3
  4 using namespace std;
  5
  6 struct Node
  7 {
  8     int l,r;
  9     int v;
 10     int lz;
 11 }bn[400000];
 12
 13 void build(int k,int l,int r)
 14 {
 15     bn[k].l=l;
 16     bn[k].r=r;
 17     bn[k].lz=0;
 18     if(bn[k].l==bn[k].r)
 19     {
 20         bn[k].v=0;
 21         return ;
 22     }
 23     int lk=k*2;
 24     int rk=lk+1;
 25     int mid=(l+r)/2;
 26     build(lk,l,mid);
 27     build(rk,mid+1,r);
 28     bn[k].v=0;
 29 }
 30
 31 void push(int k)
 32 {
 33     int lk=k*2;
 34     int rk=lk+1;
 35     bn[lk].v+=bn[k].lz;
 36     bn[rk].v+=bn[k].lz;
 37     bn[lk].lz+=bn[k].lz;
 38     bn[rk].lz+=bn[k].lz;
 39     bn[k].lz=0;
 40 }
 41
 42 void change(int k,int l,int r)
 43 {
 44     if(bn[k].l==l&&bn[k].r==r)
 45     {
 46         bn[k].lz++;
 47         bn[k].v=bn[k].lz*(bn[k].r-bn[k].l+1);
 48         return ;
 49     }
 50     if(bn[k].lz)
 51         push(k);
 52     int lk=k*2;
 53     int rk=lk+1;
 54     if(bn[lk].r>=r)
 55         change(lk,l,r);
 56     else if(bn[rk].l<=l)
 57         change(rk,l,r);
 58     else
 59     {
 60         change(lk,l,bn[lk].r);
 61         change(rk,bn[rk].l,r);
 62     }
 63     bn[k].v=bn[rk].v+bn[lk].v;
 64 }
 65
 66 int ans;
 67 void search(int k,int i)
 68 {
 69     if(bn[k].l==i&&bn[k].r==i)
 70     {
 71         ans=bn[k].v;
 72         return ;
 73     }
 74     if(bn[k].lz)
 75         push(k);
 76     int lk=k*2;
 77     int rk=lk+1;
 78     if(bn[lk].r>=i)
 79         search(lk,i);
 80     else if(bn[rk].l<=i)
 81         search(rk,i);
 82     bn[k].v=bn[rk].v+bn[lk].v;
 83 }
 84
 85 int main()
 86 {
 87     int n;
 88     while(cin>>n&&n)
 89     {
 90         int a,b;
 91         build(1,1,n);
 92         for(int i=1;i<=n;i++)
 93         {
 94             scanf("%d%d",&a,&b);
 95             change(1,a,b);
 96         }
 97         search(1,1);
 98         cout<<ans;
 99         for(int i=2;i<=n;i++)
100         {
101             search(1,i);
102             cout<<" "<<ans;
103         }
104         cout<<endl;
105     }
106     return 0;
107 }

这是正常线段树做法

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4
 5 using namespace std;
 6
 7 int an[100010];
 8 int ans[100010];
 9
10 int main()
11 {
12     int n;
13     while(cin>>n&&n)
14     {
15         memset(an,0,sizeof(an));
16         memset(ans,0,sizeof(ans));
17         int a,b;
18         for(int i=1;i<=n;i++)
19         {
20             scanf("%d%d",&a,&b);
21             an[a]+=1;
22             an[b+1]+=-1;
23         }
24         for(int i=1;i<=n;i++)
25         {
26             ans[i]=ans[i-1]+an[i];
27         }
28         cout<<ans[1];
29         for(int i=2;i<=n;i++)
30         {
31             cout<<" "<<ans[i];
32         }
33         cout<<endl;
34     }
35     return 0;
36 }

简便方法,时间复杂度为N

时间: 2024-11-05 23:27:26

区间修改点查询 HDU1556的相关文章

Wikilo 1191线段树区间修改单点查询

这题也算比较容易的了. 如果哪个区间已经没有黑色的话,就不用update了,就是因为这个原因WA了2发,唉-- #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #incl

【树状数组区间修改单点查询+分组】HDU 4267 A Simple Problem with Integers

http://acm.hdu.edu.cn/showproblem.php?pid=4267 [思路] 树状数组的区间修改:在区间[a, b]内更新+x就在a的位置+x. 然后在b+1的位置-x 树状数组的单点查询:求某点a的值就是求数组中1~a的和. (i-a)%k==0把区间分隔开了,不能直接套用树状数组的区间修改单点查询 这道题的K很小,所以可以枚举k,对于每个k,建立k个树状数组,所以一共建立55棵树 所以就可以多建几棵树..然后就可以转换为成段更新了~~ [AC] 1 #include

洛谷 P3368 【模板】树状数组 2 如题(区间修改+单点查询)

P3368 [模板]树状数组 2 时空限制1s / 128MB 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含2或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x 含义:输出

线段树区间修改与查询

单点修改与查询 //单点修改,区间询问最小值 #include <iostream> #include <cstdio> #define maxn 101 #define INF 0x7fffffff using namespace std; int a[maxn],n,m; int mi[maxn]; void build(int k,int l,int r)//k是当前节点编号,l,r为当前节点代表区间 { if(l==r) { mi[k]=a[l]; return; } in

基本线段树模板(建树、点/区间修改、查询)

线段树主要用于区间记录信息(如区间和.最大最小值等),首先是建树: 这里以求和为例: 1 const int MAXM=50000; //定义 MAXM 为线段最大长度 2 3 int a[MAXM+5],segtree[(MAXM<<2)+5]; // a 数组为 main 函数中读入的内容,segtree 数组为需要查询的数的信息(如和.最值等),树的空间大小为线段最大长度的四倍 4 5 void build(int o,int l,int r){ //传入的参数为 o:当前需要建立的结点

POJ 3468 A Simple Problem with Integers(线段树区间修改及查询)

Description You have N integers, A1, A2, ... , 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. In

AcWing 242 一个简单整数问题(区间修改 单点查询)

原题 该题涉及树状数组又一串操作: ① 区间修改 运用差分的思想,我们新建了一个数组b,初始化为零,对于每个指令"C l r d",我们只需将其转化为以下操作: 1.把b[l]加上d 2.再把b[r+1]减去d inline void add(int x,int y) { for(;x<=n;x+=x&-x) { c[x]+=y; } } add(l,j); add(r+1,-j); ② 单点查询 执行了以上操作后,b数组的前缀和b[1~x]就代表了该指令对a[x]的影响

树状数组模板(区间修改+单点查询)

很巧妙的用了差分建树,解决区间修改的问题 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=5e5+5; 5 6 int n,m; 7 int a[maxn]; 8 ll tree[maxn]; 9 10 int lowbit(int x){ 11 return x&(-x); 12 } 13 14 void add(int idx,int v){ 15

poj3468 splay区间修改和查询

线段树的题目,拿来练第一道splay维护区间. 像这种基本的操作修改查询,我现在应该能在20分钟手写好splay再用10分钟调试,基本上不靠模版30分钟应该能出. //#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define key_val ch[