hdu 4288 线段树 暴力 **
题意:
维护一个有序数列{An},有三种操作:
1、添加一个元素。
2、删除一个元素。
3、求数列中下标%5 = 3的值的和。
解题思路:
看的各种题解,今天终于弄懂了。
由于线段树中不支持添加、删除操作,所以题解写的是用离线做法。
我们来看它是如何解决添加、删除的问题的。
首先将所有出现过的数记录下来,然后排序去重,最后根据去重结果建树,然后每个操作数都会对应线段树中的一个点。
遇到添加、删除操作的时候,只要把那个节点的值改变,然后将它对下标的影响处理好就可以。
那么如何处理这些操作对下标的影响呢?
现在我们考虑一个父区间,假设它的左右子区间已经更新完毕。
显然,左区间中下标%5的情况与父区间中%5的情况完全相同;
可是,右区间中却不一定相同,因为右区间中的下标是以 mid 当作 1 开始的。
那么,只要我们知道左区间中有效元素的个数 cnt,我们就能知道右区间中的下标 i 在父区间中对应的下标为 i+cnt。
所以,虽然我们最终要的只是总区间中下标%5 = 3的和。但是在更新时我们需要知道右区间%5的所有情况。
于是我们要在线段树的每个节点开一个 sum[5] 和一个 cnt,分别记录这个节点中下标%5的5种情况的和与有效元素的个数。
而查询时,直接访问总区间的 sum[3] 即可。
如此,题目便可解了。复杂度O(M logN logN)。
以前用的是线段树,这次用暴力来了一发
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define MOD 1000000007
const int INF=0x3f3f3f3f;
const double eps=1e-;
typedef long long ll;
#define cl(a) memset(a,0,sizeof(a))
#define ts printf("*****\n");
const int N=;
int n,m,tt;
int main()
{
int i,j,k,ca=;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
while(scanf("%d",&n)!=EOF)
{
int len=;
vector<int> vc;
int x;
vector<int>::iterator it;
char s[];
while(n--)
{
scanf("%s",s);
if(s[]=='a')
{
len++;
scanf("%d",&x);
it=lower_bound(vc.begin(),vc.end(),x);
vc.insert(it,x);
}
else if(s[]=='d')
{
len--;
scanf("%d",&x);
it=lower_bound(vc.begin(),vc.end(),x);
vc.erase(it);
}
else
{
ll sum=;
for(i=;i<len;i+=)
{
sum+=vc[i];
}
printf("%I64d\n",sum);
}
}
}
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root 1,n,1
#define mid ((l+r)>>1)
#define ll long long
#define cl(a) memset(a,0,sizeof(a))
#define ts printf("*****\n");
using namespace std;
const int MAXN=;
ll sum[MAXN<<][];
vector<int> num;
int cnt[MAXN<<],val[MAXN];
char cz[MAXN],s[];
int n,m,t;
int getid(int v)
{
return lower_bound(num.begin(),num.end(),v)-num.begin()+;
}
void pushup(int rt)
{
cnt[rt]=cnt[rt<<]+cnt[rt<<|];
for(int i=;i<;i++) sum[rt][i]=sum[rt<<][i];
for(int i=;i<;i++) sum[rt][(i+cnt[rt<<])%]+=sum[rt<<|][i]; //这两个不能放一起,找了好长时间
}
int tot=;
void update(int pos,int v,int l,int r,int rt)
{
if(l==r)
{
sum[rt][]=num[pos-]*v;
cnt[rt]=v;
return;
}
if(pos<=mid) update(pos,v,lson);
else update(pos,v,rson);
pushup(rt);
}
int main()
{
int i,j,k,q;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
while(~scanf("%d",&n))
{
num.clear();
for(i=;i<=n;i++)
{
scanf("%s",s);
cz[i]=s[];
if(s[]!='s')
{
scanf("%d",val+i);
num.push_back(val[i]);
}
}
cl(sum),cl(cnt);
sort(num.begin(),num.end());
num.erase(unique(num.begin(),num.end()),num.end());
int sumn=num.size();
for(int i=;i<=n;i++)
{
if(cz[i] == 'a') update(getid(val[i]),,,sumn,);
else if(cz[i] == 'd') update(getid(val[i]),,,sumn,);
else printf("%I64d\n",sum[][]);
}
}
return ;
}
hdu 4288 线段树 暴力 **的更多相关文章
- hdu 6430 线段树 暴力维护
Problem E. TeaTree Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Oth ...
- V - Can you answer these queries? HDU - 4027 线段树 暴力
V - Can you answer these queries? HDU - 4027 这个题目开始没什么思路,因为不知道要怎么去区间更新这个开根号. 然后稍微看了一下题解,因为每一个数开根号最多开 ...
- hdu 4288 线段树+离线+离散化
http://acm.hdu.edu.cn/showproblem.php?pid=4288 開始的时候,果断TLE,做的方法是,线段树上只维护%5==3的坐标,比方1 2 3 4 5 6 7 假设 ...
- HDU 4288 线段树+离散化
题意: n个操作 在[1, 100000] 的区间上add 或del数( 必不会重复添加或删除不存在的数) sum 求出整个集合中 (下标%5 == 3 位置) 的数 的和 注意数据类型要64位 ...
- hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
随机推荐
- JS 对象遍历
var orgRoot = { 271: {backgroundColor: '#f68f2b', textColor: '#FFFFFF'}, 272: {backgroundColor: '#49 ...
- 【leetcode】Binary Tree Maximum Path Sum
Binary Tree Maximum Path Sum Given a binary tree, find the maximum path sum. The path may start and ...
- mongoengine
http://docs.mongodb.org/ecosystem/drivers/python/ http://www.cnblogs.com/holbrook/archive/2012/03/11 ...
- Intellij Idea 14 生成serialVersionUID的方法
默认情况下Intellij IDEA是关闭了继承了java.io.Serializable的类生成serialVersionUID的警告.如果需要ide提示生成serialVersionUID,那么需 ...
- Java实验四和实验五
实验四 类的继承性和多态性 [开发语言及实现平台或实验环境] Windows2000 或XP,JDK1.6与Jcreator4.0 [实验目的] 1. 掌握OOP方式进行程序设计的方法, 2. 了 ...
- java wait()和notify()、notifyAll()
图见<JAVA并发编程的艺术>P98-101 这三个方法都是java.lang.Object的方法,用于协调多个线程对共享数据的存取,必须在synchronized语句块中使用!这三个方法 ...
- SQL中关于字符串的处理
DECLARE @STR VARCHAR(MAX),@PRAM VARCHAR(20)SET @STR='中华人民共和国万岁'--字符串连接SET @STR=@STR+'an'+@STR --字符串拆 ...
- GCD 大中枢派发 简单应用实例
@interface ViewController () { UIImageView* iv; UIButton* btn; UILabel* lbl; } @end @implementation ...
- IOS 推送消息 php做推送服务端
IOS推送消息是许多IOS应用都具备的功能,最近也在研究这个功能,参考了很多资料终于搞定了,下面就把步骤拿出来分享下: iOS消息推送的工作机制可以简单的用下图来概括: Provider是指某个iPh ...
- dropdownlist 动态添加
this.DropDownList1.Items.Insert(0,new ListItem("","")); this.Drop ...