hdu 1166 敌兵布阵(cdq分治)
2017-07-04 20:52
513 查看
第一次听了cdq分治,然后着手开始写了一下。
其实就是把操作全部记录下来,注意当前的操作其实就是已经按照时间排好序的。
我们把它按照时间分治,也就是类似归并排序那样,分治。然后每次计算并记录时间早(左区间)对时间晚的(右区间)的一个影响。
具体的看代码可能更好理解一下。
可以参考这里:
http://blog.csdn.net/braketbn/article/details/51187181
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 2e5+7;
int n;
int pid,aid;
struct node
{
int index;
int val;
int type;
bool operator <= (const node &a)const
{
return index == a.index?type < a.type : index < a.index;
}
} p[MAXN],temp[MAXN];
int ans[MAXN];
void cdq(int l,int r)
{
if(l >= r)return ;
int mid = (l+r)>>1;
cdq(l,mid);
cdq(mid+1,r);
int i = l, j = mid+1;
int sum = 0,cnt = 0;
while(i <= mid && j <= r)
{
if(p[i] <= p[j])
{
if(p[i].type == 1)sum += p[i].val;
else if(p[i].type == 2)sum -= p[i].val;
temp[cnt++] = p[i++];
}
else
{
if(p[j].type == 3)ans[p[j].val] -= sum;
else if(p[j].type == 4)ans[p[j].val] += sum;
temp[cnt++] = p[j++];
}
}
while(i <= mid)
{
temp[cnt++] = p[i++];
}
while(j <= r)
{
if(p[j].type == 3)ans[p[j].val] -= sum;
else if(p[j].type == 4)ans[p[j].val] += sum;
temp[cnt++] = p[j++];
}
for(int i = 0 ; i < cnt ; ++i)p[l++] = temp[i];
}
int main()
{
int t;
char s[10];
scanf("%d",&t);
for(int tt = 1 ; tt <= t ; ++tt)
{
memset(ans,0,sizeof ans);
pid = aid = 0;
scanf("%d",&n);
for(int i = 1 ; i <= n ; ++i)
{
scanf("%d",&p[++pid].val);
p[pid].index = i;
p[pid].type = 1;
}
int l,r;
while(scanf("%s",s) && s[0]!='E')
{
scanf("%d%d",&l,&r);
if(s[0] == 'Q')
{
p[++pid].index = l-1;
p[pid].type = 3;
p[pid].val = aid;
p[++pid].index = r;
p[pid].type = 4;
p[pid].val = aid++;
}
else
{
p[++pid].index = l;
p[pid].val = r;
if(s[0] == 'A')p[pid].type = 1;
else p[pid].type = 2;
}
}
cdq(1,pid);
printf("Case %d:\n",tt);
for(int i = 0 ; i < aid ; ++i)printf("%d\n",ans[i]);
}
return 0;
}
其实就是把操作全部记录下来,注意当前的操作其实就是已经按照时间排好序的。
我们把它按照时间分治,也就是类似归并排序那样,分治。然后每次计算并记录时间早(左区间)对时间晚的(右区间)的一个影响。
具体的看代码可能更好理解一下。
可以参考这里:
http://blog.csdn.net/braketbn/article/details/51187181
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 2e5+7;
int n;
int pid,aid;
struct node
{
int index;
int val;
int type;
bool operator <= (const node &a)const
{
return index == a.index?type < a.type : index < a.index;
}
} p[MAXN],temp[MAXN];
int ans[MAXN];
void cdq(int l,int r)
{
if(l >= r)return ;
int mid = (l+r)>>1;
cdq(l,mid);
cdq(mid+1,r);
int i = l, j = mid+1;
int sum = 0,cnt = 0;
while(i <= mid && j <= r)
{
if(p[i] <= p[j])
{
if(p[i].type == 1)sum += p[i].val;
else if(p[i].type == 2)sum -= p[i].val;
temp[cnt++] = p[i++];
}
else
{
if(p[j].type == 3)ans[p[j].val] -= sum;
else if(p[j].type == 4)ans[p[j].val] += sum;
temp[cnt++] = p[j++];
}
}
while(i <= mid)
{
temp[cnt++] = p[i++];
}
while(j <= r)
{
if(p[j].type == 3)ans[p[j].val] -= sum;
else if(p[j].type == 4)ans[p[j].val] += sum;
temp[cnt++] = p[j++];
}
for(int i = 0 ; i < cnt ; ++i)p[l++] = temp[i];
}
int main()
{
int t;
char s[10];
scanf("%d",&t);
for(int tt = 1 ; tt <= t ; ++tt)
{
memset(ans,0,sizeof ans);
pid = aid = 0;
scanf("%d",&n);
for(int i = 1 ; i <= n ; ++i)
{
scanf("%d",&p[++pid].val);
p[pid].index = i;
p[pid].type = 1;
}
int l,r;
while(scanf("%s",s) && s[0]!='E')
{
scanf("%d%d",&l,&r);
if(s[0] == 'Q')
{
p[++pid].index = l-1;
p[pid].type = 3;
p[pid].val = aid;
p[++pid].index = r;
p[pid].type = 4;
p[pid].val = aid++;
}
else
{
p[++pid].index = l;
p[pid].val = r;
if(s[0] == 'A')p[pid].type = 1;
else p[pid].type = 2;
}
}
cdq(1,pid);
printf("Case %d:\n",tt);
for(int i = 0 ; i < aid ; ++i)printf("%d\n",ans[i]);
}
return 0;
}
相关文章推荐
- hdu 1166 敌兵布阵(cdq分治)
- hdu 1166 敌兵布阵 线段树
- HDU 1166 敌兵布阵(线段树)
- HDU 1166 敌兵布阵(线段树,树状数组)
- 整理的树状数组模板 & 敌兵布阵 HDU - 1166
- HDU 1166-敌兵布阵(线段树:单点更新,区间求和)
- HDU 1166 敌兵布阵
- HDU - 1166 - 敌兵布阵(树状数组、线段树)
- HDU-1166 敌兵布阵
- hdu 1166 敌兵布阵——(区间和)树状数组/线段树
- HDU 1166 敌兵布阵【线段树-单点更新】
- HDU 1166 敌兵布阵 【线段树(单点增减 区间求和)】
- HDU-1166-敌兵布阵
- hdu-1166敌兵布阵(树状数组)
- 线段树 hdu 1166 敌兵布阵 单点更新区间求和
- hdu 1166 敌兵布阵 (线段树)
- hdu 1166 敌兵布阵
- [线段树] HDU 1166 - 敌兵布阵
- HDU 1166 敌兵布阵 (线段树单点更新 区间查询)
- hdu 1166 敌兵布阵