http://codeforces.com/contest/121/problem/E

话说这题貌似暴力可A啊。。。

正解是想出来了,结果重构代码,调了不知道多久才A

错误记录:

1.线段树搞混num(节点编号)和l(区间端点)

2.之前的dfs没有分离,写的非常混乱,迫不得已重构代码

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define N 100000
int data[]={,,,,,,,,,,,,,,
,,,,,,,,,,,,
,,,};
bool ok[];
int sd=;
int n,m;
int d[N+];
vector<pii> qq;
//d[i]表示满足data[j]>(i位置的实际值)的最小j
//线段树中查询出的位置的值表示data[d[i]]-(i位置的实际值)
namespace S
{
#define mid (l+((r-l)>>1))
#define lc (num<<1)
#define rc (num<<1|1)
int minn[*N],sum[*N],delv[*N];
void pd(int num)
{
minn[lc]-=delv[num];minn[rc]-=delv[num];
delv[lc]+=delv[num];delv[rc]+=delv[num];
delv[num]=;
}
void delx(int L,int R,int x,int l,int r,int num)
{
if(L<=l&&r<=R)
{
minn[num]-=x;delv[num]+=x;
return;
}
pd(num);
if(L<=mid) delx(L,R,x,l,mid,lc);
if(mid<R) delx(L,R,x,mid+,r,rc);
minn[num]=min(minn[lc],minn[rc]);
}
void setx(int L,int x,int l,int r,int num)
{
if(l==r) {minn[num]=x;return;}
pd(num);
if(L<=mid) setx(L,x,l,mid,lc);
else setx(L,x,mid+,r,rc);
minn[num]=min(minn[lc],minn[rc]);
}
void setsum(int L,int x,int l,int r,int num)
{
if(l==r) {sum[num]=x;return;}
if(L<=mid) setsum(L,x,l,mid,lc);
else setsum(L,x,mid+,r,rc);
sum[num]=sum[lc]+sum[rc];
}
void update(int l,int r,int num)
{
if(minn[num]>) return;
if(l==r) {qq.pb(mp(l,data[d[l]]-minn[num]));return;}//minn[l]->minn[num]
pd(num);
update(l,mid,lc);update(mid+,r,rc);
minn[num]=min(minn[lc],minn[rc]);
}
int gsum(int L,int R,int l,int r,int num)
{
if(L<=l&&r<=R) return sum[num];
int ans=;
if(L<=mid) ans+=gsum(L,R,l,mid,lc);
if(mid<R) ans+=gsum(L,R,mid+,r,rc);
return ans;
}
void work()
{
for(auto pp:qq)
{
int &l=pp.fi,&d=pp.se;
int p=upper_bound(data,data+sd,d)-data;
setx(l,data[p]-d,,n,);
setsum(l,ok[d],,n,);
::d[l]=p;
}
qq.clear();
}
}
char tmp[];
int main()
{
int i,t,L,R,x;
for(i=;i<sd;i++) ok[data[i]]=;
for(i=;i<sd;i++) data[i+sd]=data[i]+;
sd*=;sort(data,data+sd);
data[sd++]=;
scanf("%d%d",&n,&m);
for(i=;i<=n;i++) scanf("%d",&t),qq.pb(mp(i,t));
S::work();
while(m--)
{
scanf("%s",tmp);
if(tmp[]=='c')
{
scanf("%d%d",&L,&R);S::update(,n,);S::work();
printf("%d\n",S::gsum(L,R,,n,));
}
else
{
scanf("%d%d%d",&L,&R,&x);
S::delx(L,R,x,,n,);
}
}
return ;
}

https://codeforces.com/problemset/problem/679/E

跟上面那道类似,可以发现涉及到42的幂很少(显然出题人不是想让我们写高精)

因此开一棵线段树维护每个位置到下一个“关键点”(是否是42的幂的属性变化的点)的距离即可

对于区间修改,就用set维护一下相同的区间,一段相同的放在一起处理

大概是这样吧,可能还有一些细节。。

最新文章

  1. window系统JDK1.7的快速配置
  2. office在线预览方案
  3. php configure help
  4. Spring MVC常用的注解
  5. Python下载漫画
  6. C# sql操作
  7. js实现鼠标拖拽div-------Day44
  8. PHP 4:从Login进一步看到的
  9. Android项目-高考作文-AsyncTask的不足
  10. css 椭圆样式
  11. ftp 发布配置
  12. 选择文件,显示其路径在ListBox控件里
  13. Linux内核线程kernel thread详解--Linux进程的管理与调度(十)
  14. 用Flask+Redis维护Cookies池
  15. Xamarin.Android部署失败
  16. C# 验证给定的字符串形式的日期是否合法
  17. Hive的介绍及安装
  18. oracle 批量更新表字段
  19. html学习第一天
  20. 河流Shader

热门文章

  1. 利用NSMutableAttributedString实现label上字体大小颜色行间距的改变
  2. 宠物连连看2完整Android代码项目
  3. Android app身体质量指数(BMI)
  4. 例子:两个表根据productID合并
  5. firefox 45 版本
  6. C++设计模式之State模式
  7. file类简单操作
  8. jdbc navcat for mysql 连不上远程服务器的原因(安全组设置)
  9. spring boot 使用Ehcache
  10. 一步一步学Silverlight 2系列(24):与浏览器交互相关辅助方法