上午:
HDU 5372 Segment Game(线段树)
覆盖区间数=左端点大于L-右端点大于R
由于区间比较大,所以进行离散化处理
然后树状数组维护一下就可以了
The shortest problem(hdu5373+11的倍数)
结论题:能被11整除的数字,奇数和偶数位之和的差可以被11整除。
HDU 5381 The sum of gcd(莫队+rmq+二分):
由于n比较小先用rmq+二分预处理一下gcd变换的位置
然后莫队处理区间移动就行了
HDU 5377 Root(扩展欧几里得 + 生成元)
小范围暴力+大范围bsgs裸题,因为比较大的质因子只可以有一个
HDU 5386 Cover
逆向思维,在已知结果的前提下看看这个操做是否合法,合法则记录路径并更新对应行或者列为任意颜色即可
HDU 5387 Clock
模拟指针的移动就行了,为了防止除不尽,全部扩大120倍在进行处理
下午:
一看1005计算几何题目有好多人过,找了个假模板搞了两小时,后来发现就是一个公式,肝到怀疑人生。之后线段树维护最大值和lazy标记,最后tle,结果赛后改成维护最小值就过了......分析一下应该和数据的随机性有关系,实际更新次数并不多
上午:
一到比赛就发现线段树模板没得用,手敲又种种出错,所以今天打算看看多校的线段树题目顺便来整理几套能用的模板,毕竟线段树是我的专长,老是坑模板有些难受
杭电多校第二场1007 Naive Operations(线段树七十二变)
之前做的一道线段树多校题目,维护b[i]-a[i],和最小值,然后如果需要更新暴力更新到单点,同时树状数组维护sum,当时我的思路和题解完全相同,又是没有模板不敢敲系列
发现越是像线段树的题目越是没有什么胆量写,这里维护标记表示该区间的数是否全部修改为斐波那契数,一个数组表示和这个区间最近的斐波那契数,一个维护与这个值最近的斐波那切数,做一般的区间更新和单点更新即可
HDU 5828 多校第八场 1008 Rikka with Sequence(线段树--数据加强版)
又是一发线段树优化,区间更新+区间求sqrt+区间查询
线段树的时间复杂度真的是个好东西,一开始看的一个题解,分析了半天最后说这个题目我放弃,也是醉了。
细节多点,不过是个线段树优化的好题,lazy+cover数据优化+输入挂可过
标程解法用极差,就是区间最大值和区间最小值,若相同,直接开方,若极差为一,也可以特殊处理。不过更新完需要pushdown一次
hdu6070 二分+线段树 2017多校第四场1004
其实是个0-1的分数规划,用线段树维护一下出现的值就可以了,这里又一次理解了一下0-1规划
下午:
这里求gcd和l,r相同的区间的个数
很巧妙的利用了线段树的性质,找到了每次gcd的下降的位置,记录达到加速的目的
单点更新,区间查询(地兵布阵):
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxn 400010
using namespace std;
struct xtree{
long long l,r;
long long sum;
//long long maxx;
//long long minn;
long long mid(){
return (l+r)/2;
}
}tree[maxn];
long long a[maxn];
void pushup(long long id){
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
//tree[id].maxx=max(tree[id*2].maxx,tree[id*2+1].maxx);
//tree[id].minn=max(tree[id*2].minn,tree[id*2+1].minn);
}
void build(long long id,long long l,long long r){
tree[id].l=l;
tree[id].r=r;
if (l==r){
tree[id].sum=a[l];
//tree[id].maxx=tree[id].minn=a[l];
return ;
}
long long mid=tree[id].mid();
build(id*2,l,mid);
build(id*2+1,mid+1,r);
pushup(id);
}
void update(long long id,long long pos,long long val){
if (tree[id].l==tree[id].r){
tree[id].sum+=val;
//tree[id].maxx=tree[id].minn=tree[id].sum;
return ;
}
long long mid=tree[id].mid();
if (pos<=mid){
update(id*2,pos,val);
}
else {
update(id*2+1,pos,val);
}
pushup(id);
}
long long query(long long id,long long l,long long r){
if (tree[id].l>=l&&tree[id].r<=r){
return tree[id].sum;
}
long long mid=tree[id].mid();
if (r<=mid){
return query(id*2,l,r);
}
else if (l>mid){
return query(id*2+1,l,r);
}
else {
return query(id*2,l,mid)+query(id*2+1,mid+1,r);
}
}
int main(){
long long t;
long long i,j;
long long n,m,x,y,z;
scanf("%lld",&t);
long long cas=0;
while (t--){
scanf("%lld",&n);
for (i=1;i<=n;i++)scanf("%lld",&a[i]);
build(1,1,n);
char fun[11];
printf("Case %lld:\n",++cas);
while (1){
scanf("%s",&fun);
if (fun[0]=='E')break;
else if (fun[0]=='A'){
scanf("%lld%lld",&x,&y);
update(1,x,y);
}
else if (fun[0]=='S'){
scanf("%lld%lld",&x,&y);
update(1,x,-y);
}
else {
scanf("%lld%lld",&x,&y);
long long ans=query(1,x,y);
printf("%lld\n",ans);
}
}
}
}
区间更新,区间查询(Color the ball):
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#define maxn 400010
using namespace std;
struct xtree{
long long l,r;
long long lazy;
long long sum;
long long mid(){
return (l+r)/2;
}
}tree[maxn];
long long a[maxn];
void pushup(long long id){
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
}
void pushdown(long long id){
if (tree[id].lazy){
tree[id*2].lazy+=tree[id].lazy;
tree[id*2+1].lazy+=tree[id].lazy;
long long mid=tree[id].mid();
tree[id*2].sum+=tree[id].lazy*(mid-tree[id].l+1);
tree[id*2+1].sum+=tree[id].lazy*(tree[id].r-mid);
tree[id].lazy=0;
}
}
void build(long long id,long long l,long long r){
tree[id].l=l;
tree[id].r=r;
tree[id].lazy=0;
if (l==r){
tree[id].sum=0;
//tree[id].sum=a[l];
return ;
}
long long mid=tree[id].mid();
build(id*2,l,mid);
build(id*2+1,mid+1,r);
pushup(id);
}
void update(long long id,long long l,long long r,long long val){
if (tree[id].l>=l&&tree[id].r<=r){
tree[id].lazy+=val;
tree[id].sum+=(tree[id].r-tree[id].l+1)*val;
return ;
}
pushdown(id);
long long mid=tree[id].mid();
if (r<=mid){
update(id*2,l,r,val);
}
else if (l>mid){
update(id*2+1,l,r,val);
}
else {
update(id*2,l,mid,val);
update(id*2+1,mid+1,r,val);
}
pushup(id);
}
long long query(long long id,long long l,long long r){
if (tree[id].l>=l&&tree[id].r<=r){
return tree[id].sum;
}
pushdown(id);
long long mid=tree[id].mid();
if (r<=mid){
return query(id*2,l,r);
}
else if (l>mid){
return query(id*2+1,l,r);
}
else {
return query(id*2,l,r)+query(id*2+1,l,r);
}
}
int main(){
long long n,x,y;
long long i;
while (scanf("%lld",&n)!=EOF&&n){
build(1,1,n);
for (i=1;i<=n;i++){
scanf("%lld%lld",&x,&y);
update(1,x,y,1);
}
for (i=1;i<=n;i++){
printf("%lld%c",query(1,i,i),i==n?'\n':' ');
}
}
}