您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cdq分治