1. HDU-1166 敌兵布阵
解题思路:版模题
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 50000 << 2;
int num[maxn], S[maxn], L[maxn], R[maxn];
void build(int u, int l ,int r) {
if(l == r) {
S[u] = num[l];
L[u] = R[u] = l;
return ;
}
int mid = (l + r) / 2;
build(2*u,l,mid);
build(2*u+1,mid+1,r);
S[u] = S[2*u] + S[2*u+1];
L[u] = l;
R[u] = r;
}
void add(int i,int j, int r) {
if(R[r] == i && L[r] == i) {
S[r] += j;
return ;
}
int mid = (L[r] + R[r]) / 2;
if(i <= mid)
add(i,j,2*r);
else
add(i,j,2*r+1);
S[r] += j;
}
void Sub(int i,int j, int r) {
if(R[r] == i && L[r] == i) {
S[r] -= j;
return ;
}
int mid = (L[r] + R[r]) / 2;
if(i <= mid)
Sub(i,j,2*r);
else
Sub(i,j,2*r+1);
S[r] -= j;
}
int Query(int i, int j, int r) {
if( i <= L[r] && R[r] <= j)
return S[r];
int mid = (L[r] + R[r]) / 2;
int ans = 0;
if (i <= mid)
ans += Query(i,j,2*r);
if (j > mid)
ans += Query(i,j,2*r+1);
return ans;
}
int main() {
int test, N, mark = 1;
char temp[100];
scanf("%d",&test);
while(test--) {
scanf("%d",&N);
for(int i = 1; i <= N; i++)
scanf("%d",&num[i]);
build(1,1,N);
int i,j;
getchar();
printf("Case %d:\n",mark++);
while(1) {
scanf("%s",temp);
if (temp[0] == 'E')
break;
scanf("%d%d", &i, &j);
getchar();
if(strcmp("Add",temp) == 0)
add(i,j,1);
else if(strcmp("Sub",temp) == 0)
Sub(i,j,1);
else if(strcmp("Query",temp) == 0)
printf("%d\n",Query(i,j,1));
}
}
return 0;
}
2.HDU 1754 I Hate it
解题思路:模板题
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 200000 << 2;
int S[maxn], L[maxn], R[maxn];
int num[maxn];
void build(int u, int l, int r) {
if( l == r) {
S[u] = num[l];
L[u] = l;
R[u] = l;
return ;
}
int mid = (l + r) / 2;
build(2*u,l,mid);
build(2*u+1,mid+1,r);
S[u] = max(S[2*u],S[2*u+1]);
L[u] = l;
R[u] = r;
}
void modify(int id, int x, int u) {
if(L[x] == id && R[x] == id) {
S[x] = u;
return ;
}
int mid = (L[x] + R[x]) / 2;
if(id <= mid)
modify(id,2*x,u);
else
modify(id,2*x+1,u);
S[x] = max(S[2*x],S[2*x+1]);
}
int search(int s, int e, int u) {
if(L[u] >= s && R[u] <= e)
return S[u];
int mid = (L[u] + R[u]) / 2;
if(s >= mid + 1)
return search(s,e,2*u+1);
else if(e <= mid)
return search(s,e,2*u);
else
return max(search(s,e,2*u),search(s,e,2*u+1));
}
int main() {
int N, M;
int test;
while(scanf("%d%d",&N,&M) == 2) {
for(int i = 1; i <= N; i++)
scanf("%d",&num[i]);
build(1,1,N);
getchar();
int s, e;
char c;
for(int i = 0; i < M; i++) {
scanf("%c%d%d",&c,&s,&e);
getchar();
if(c == 'Q')
printf("%d\n",search(s,e,1));
else
modify(s,1,e);
}
}
return 0;
}
3.
UVA - 12299 RMQ with Shifts
解题思路:shift移动的话,就把相应节点的值改变一下,再把原数组改变一下就可以了
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100010 << 2;
int num[maxn >> 2], S[maxn], R[maxn], L[maxn];
void build(int u, int l ,int r) {
L[u] = l;
R[u] = r;
if(l == r) {
S[u] = num[l];
return;
}
int mid = (l + r) / 2;
build(2 * u, l , mid);
build(2 * u + 1, mid + 1, r);
S[u] = min(S[2 * u], S[2 * u + 1]);
}
int query(int l, int r, int u) {
if(l <= L[u] && R[u] <= r)
return S[u];
int mid = (L[u] + R[u]) / 2;
if(r <= mid)
return query(l, r, 2 * u);
else if(l > mid)
return query(l, r, 2 * u + 1);
else
return min(query(l , r, 2 * u) , query(l, r, 2 * u + 1));
}
void shift(int x, int v, int u) {
if(x == L[u] && R[u] == x) {
S[u] = v;
return ;
}
int mid = (L[u] + R[u]) / 2;
if(x <= mid)
shift(x, v, 2 * u);
else
shift(x, v, 2 * u + 1);
S[u] = min(S[2 * u], S[2 * u + 1]);
}
int main() {
int N, Q;
scanf("%d%d", &N, &Q);
for(int i = 1; i <= N; i++)
scanf("%d",&num[i]);
build(1,1,N);
char str[300];
while(Q--) {
scanf("%s",str);
if(str[0] == 'q') {
int s, e;
sscanf(str,"query(%d,%d)",&s,&e);
printf("%d\n",query(s,e,1));
}
else {
int t[30] = {0};
int cnt = 0;
for(int i = 6; str[i] != ')'; i++) {
if(str[i] == ',') {
cnt++;
continue;
}
t[cnt] = ( t[cnt] * 10 ) + str[i] - '0';
}
int temp = num[t[0]];
for(int i = 0; i < cnt; i++) {
shift(t[i], num[t[i+1]], 1);
num[t[i]] = num[t[i+1]];
}
shift( t[cnt], temp, 1);
num[t[cnt]] = temp;
}
}
return 0;
}
4.
POJ - 2886 Who Gets the Most Candies
#include<cstdio>
#include<cstring>
const int maxn = 500010 << 2;
int S[maxn],L[maxn],R[maxn], ans[maxn >> 2], num[maxn >> 2];
char name[maxn >> 2][20];
int N, K, id;
void build(int u, int l, int r) {
L[u] = l;
R[u] = r;
if(l == r) {
S[u] = 1;
return ;
}
int mid = (l + r) / 2;
build(2 * u, l , mid);
build(2 * u + 1, mid + 1, r);
S[u] = S[2 * u + 1] + S[2 * u];
}
void Solve() {
memset(ans,0,sizeof(ans));
id = 0;
for(int i = 1; i <= N; i++) {
ans[i]++;
for(int j = 2 * i; j <= N; j += i)
ans[j]++;
}
int MAX = ans[1];
for(int i = 2; i <= N; i++) {
if(ans[i] > MAX) {
MAX = ans[i];
id = i;
}
}
}
int modify(int key, int u) {
S[u]--;
if(L[u] == R[u])
return L[u];
if(S[2 * u] >= key)
return modify(key, 2 * u);
else
return modify(key - S[2 * u], 2 * u + 1);
}
int main() {
while(scanf("%d%d",&N, &K) != EOF) {
Solve();
for(int i = 1; i <= N; i++)
scanf("%s %d",name[i],&num[i]);
build(1,1,N);
num[0] = 0;
N = id;
int pos = 0;
int sum = S[1];
while(N--) {
if(num[pos] > 0)
K = ( ( K - 1 + num[pos] - 1) % sum + sum ) % sum + 1;
else
K = ( (K - 1 + num[pos] ) % sum + sum) % sum + 1;
pos = modify(K,1);
sum = S[1];
}
printf("%s %d\n",name[pos],ans[id]);
}
return 0;
}