UVA12086 Potentionmeters 线段树
2014-02-28 19:37
232 查看
A potentiometer, or potmeter for short, is an electronic device with a variable electric resistance. It has two terminals and some kind of control mechanism (often a dial, a wheel or a slide) with which the resistance between the terminals can be adjusted
from zero (no resistance) to some maximum value. Resistance is measured in Ohms, and when two or more resistors are connected in series (one after the other, in a row), the total resistance of the array is the sum of the resistances of the individual resistors.
In this problem we will consider an array of Npotmeters, numbered
1 to N from left to right. The left terminal of some potmeter numbered
x is connected to the right terminal of potmeter x-1, and its right terminal to the left terminal of potmeter
x+1. The left terminal of potmeter 1 and the right terminal of potmeter
Nare not connected.
Initially all the potmeters are set to some value between 0 and 1000 Ohms. Then we can do two things:
Set one of the potmeters to another value.
Measure the resistance between two terminals anywhere in the array.
Input
The input consists less than 3 cases. Each case starts with N, the number of potmeters in the array, on a line by itself.
N can be as large as 200000. Each of next N lines contains one numbers between 0 and 1000, the initial resistances of the potmeters in the order
1 to N. Then follow a number of actions, each on a line by itself. The number of actions can be as many as 200000. There are three types of action:
"S x r" - set potmeter x to r Ohms.
x is a valid potmeter number and r is between 0 and 1000.
"M x y" - measure the resistance between the left terminal of potmeter
x and the right terminal of potmeter y. Both numbers will be valid and
x is smaller than or equal to y.
"END" - end of this case. Appears only once at the end of a list of actions.
A case with N=0 signals the end of the input and it should not be processed.
For each measurement in the input, output a line containing one number: the measured resistance in Ohms. The actions should be applied to the array of potmeters in the order given in the input.
Print a blank line between cases.
Warning: Input Data is pretty big (~ 8 MB) so use faster IO.
卡题严重时要切切水题找状态
线段树版本:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 2000080
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
int key[maxn];
struct ST
{
int l,r,sum;
}st[maxn<<2];
void PushUp(int id)
{
st[id].sum = st[id<<1].sum + st[id<<1|1].sum;
}
void buildtree(int id,int l,int r)
{
st[id].l = l;st[id].r = r;
if(l == r)
{
st[id].sum = key[l];
return;
}
int mid = (l+r) >> 1;
buildtree(lson);
buildtree(rson);
PushUp(id);
}
void Update(int id,int pos,int k)
{
if(st[id].l == pos && st[id].r == pos)
{
st[id].sum = k;
return;
}
if(st[id<<1].r >= pos)
Update(id<<1,pos,k);
else if(st[id<<1|1].l <= pos)
Update(id<<1|1,pos,k);
PushUp(id);
}
int query(int id,int l,int r)
{
if(st[id].l == l && st[id].r == r)
return st[id].sum;
if(st[id<<1].r >= r)
return query(id<<1,l,r);
else if(st[id<<1|1].l <= l)
return query(id<<1|1,l,r);
return query(id<<1,l,st[id<<1].r) + query(id<<1|1,st[id<<1|1].l,r);
}
int main()
{
//freopen("in.txt","r",stdin);
int n,cas = 0;
while(scanf("%d",&n)!=EOF && n)
{
if(cas) printf("\n");
cas++;
for(int i = 1;i <= n;i++) scanf("%d",&key[i]);
buildtree(1,1,n);
char ope[4];
int u,v;
printf("Case %d:\n",cas);
while(1)
{
scanf("%s",ope);
if(ope[0] == 'M')
{
scanf("%d%d",&u,&v);
printf("%d\n",query(1,u,v));
}
else if(ope[0] == 'S')
{
scanf("%d%d",&u,&v);
Update(1,u,v);
}
else break;
}
}
return 0;
}
树状数组版本:似乎TLE 了???纯当练手
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 200080
int c[maxn];
int n;
int lowbit(int x)
{
return x&(-x);
}
int query(int x)
{
int ans = 0;
while(x > 0)
{
ans += c[x];
x -= lowbit(x);
}
return ans;
}
void update(int x,int set)
{
int u = x,add = 0;
while(u <= n)
{
if(u == x)
{
add = set - (query(u) - query(u-1));
}
c[u] += add;
u += lowbit(x);
}
}
int main()
{
//freopen("in.txt","r",stdin);
int cas = 0;
while(scanf("%d",&n)!=EOF && n)
{
memset(c,0,sizeof(c));
if(cas) printf("\n");
cas++;
for(int i = 1;i <= n;i++)
{
int key; scanf("%d",&key);
update(i,key);
}
char ope[4];int u,v;
printf("Case %d:\n",cas);
while(1)
{
scanf("%s",ope);
if(ope[0] == 'M')
{
scanf("%d%d",&u,&v);
printf("%d\n",query(v) - query(u-1));
}
else if(ope[0] == 'S')
{
scanf("%d%d",&u,&v);
update(u,v);
}
else break;
}
}
return 0;
}
from zero (no resistance) to some maximum value. Resistance is measured in Ohms, and when two or more resistors are connected in series (one after the other, in a row), the total resistance of the array is the sum of the resistances of the individual resistors.
In this problem we will consider an array of Npotmeters, numbered
1 to N from left to right. The left terminal of some potmeter numbered
x is connected to the right terminal of potmeter x-1, and its right terminal to the left terminal of potmeter
x+1. The left terminal of potmeter 1 and the right terminal of potmeter
Nare not connected.
Initially all the potmeters are set to some value between 0 and 1000 Ohms. Then we can do two things:
Set one of the potmeters to another value.
Measure the resistance between two terminals anywhere in the array.
Input
The input consists less than 3 cases. Each case starts with N, the number of potmeters in the array, on a line by itself.
N can be as large as 200000. Each of next N lines contains one numbers between 0 and 1000, the initial resistances of the potmeters in the order
1 to N. Then follow a number of actions, each on a line by itself. The number of actions can be as many as 200000. There are three types of action:
"S x r" - set potmeter x to r Ohms.
x is a valid potmeter number and r is between 0 and 1000.
"M x y" - measure the resistance between the left terminal of potmeter
x and the right terminal of potmeter y. Both numbers will be valid and
x is smaller than or equal to y.
"END" - end of this case. Appears only once at the end of a list of actions.
A case with N=0 signals the end of the input and it should not be processed.
Output
For each case in the input produce a line "Case n:", where n is the case number, starting from 1.For each measurement in the input, output a line containing one number: the measured resistance in Ohms. The actions should be applied to the array of potmeters in the order given in the input.
Print a blank line between cases.
Warning: Input Data is pretty big (~ 8 MB) so use faster IO.
Sample Input Output for Sample Input
3 100 100 100 M 1 1 M 1 3 S 2 200 M 1 2 S 3 0 M 2 3 END 10 1 2 3 4 5 6 7 8 9 10 M 1 10 END 0 | Case 1: 100 300 300 200 Case 2: 55 |
线段树版本:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 2000080
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
int key[maxn];
struct ST
{
int l,r,sum;
}st[maxn<<2];
void PushUp(int id)
{
st[id].sum = st[id<<1].sum + st[id<<1|1].sum;
}
void buildtree(int id,int l,int r)
{
st[id].l = l;st[id].r = r;
if(l == r)
{
st[id].sum = key[l];
return;
}
int mid = (l+r) >> 1;
buildtree(lson);
buildtree(rson);
PushUp(id);
}
void Update(int id,int pos,int k)
{
if(st[id].l == pos && st[id].r == pos)
{
st[id].sum = k;
return;
}
if(st[id<<1].r >= pos)
Update(id<<1,pos,k);
else if(st[id<<1|1].l <= pos)
Update(id<<1|1,pos,k);
PushUp(id);
}
int query(int id,int l,int r)
{
if(st[id].l == l && st[id].r == r)
return st[id].sum;
if(st[id<<1].r >= r)
return query(id<<1,l,r);
else if(st[id<<1|1].l <= l)
return query(id<<1|1,l,r);
return query(id<<1,l,st[id<<1].r) + query(id<<1|1,st[id<<1|1].l,r);
}
int main()
{
//freopen("in.txt","r",stdin);
int n,cas = 0;
while(scanf("%d",&n)!=EOF && n)
{
if(cas) printf("\n");
cas++;
for(int i = 1;i <= n;i++) scanf("%d",&key[i]);
buildtree(1,1,n);
char ope[4];
int u,v;
printf("Case %d:\n",cas);
while(1)
{
scanf("%s",ope);
if(ope[0] == 'M')
{
scanf("%d%d",&u,&v);
printf("%d\n",query(1,u,v));
}
else if(ope[0] == 'S')
{
scanf("%d%d",&u,&v);
Update(1,u,v);
}
else break;
}
}
return 0;
}
树状数组版本:似乎TLE 了???纯当练手
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 200080
int c[maxn];
int n;
int lowbit(int x)
{
return x&(-x);
}
int query(int x)
{
int ans = 0;
while(x > 0)
{
ans += c[x];
x -= lowbit(x);
}
return ans;
}
void update(int x,int set)
{
int u = x,add = 0;
while(u <= n)
{
if(u == x)
{
add = set - (query(u) - query(u-1));
}
c[u] += add;
u += lowbit(x);
}
}
int main()
{
//freopen("in.txt","r",stdin);
int cas = 0;
while(scanf("%d",&n)!=EOF && n)
{
memset(c,0,sizeof(c));
if(cas) printf("\n");
cas++;
for(int i = 1;i <= n;i++)
{
int key; scanf("%d",&key);
update(i,key);
}
char ope[4];int u,v;
printf("Case %d:\n",cas);
while(1)
{
scanf("%s",ope);
if(ope[0] == 'M')
{
scanf("%d%d",&u,&v);
printf("%d\n",query(v) - query(u-1));
}
else if(ope[0] == 'S')
{
scanf("%d%d",&u,&v);
update(u,v);
}
else break;
}
}
return 0;
}
相关文章推荐
- UVA 12086 Potentiometers(树状数组|| 线段树单点更新)
- uva12532 线段树单点更新
- uva 12086 - Potentiometers (树状数组)
- UVA1513--Movie collection--线段树
- UVA 11992 线段树
- UVA12299--线段树
- UVA 12436 - Rip Van Winkle's Code(线段树)
- UVA 12663 第九届省赛 高桥与低桥 线段树
- UVA12086 - Potentiometer(线段树/树状数组)
- UVA - 1400"Ray, Pass me the dishes!"(线段树)
- UVa 11525 - Permutation (线段树 树状数组 康托展开式)
- 【UVA】11992 - Fast Matrix Operations(线段树模板)
- 【UVA】11525-Permutation(线段树水题)
- 线段树(2):区间修改 (uva 11992 FastMatrixOperations)
- UVA - 11992 —— Fast Matrix Operations 【二维线段树转一维】
- UVA 12299 - RMQ with Shifts 线段树
- UVALive - 4108 SKYLINE (线段树的区间修改)
- UVA:11297-Census(二维线段树)
- UVa 11525 Permutation (线段树)
- uva 12086 - Potentiometers