题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006

本来应该是可以用主席树,找区间最小值,取出来后再找那段区间的次小值......

但也可以只找最小值,取出来后把原来区间分裂成两个,继续找最小值,用ST表即可;

发现自己还没写过 ST 表囧...

思路同这里:https://www.cnblogs.com/CQzhangyu/p/7071394.html

自己写了半天,才10分...奋力改了改,那个 find 里面 r++ 而 l 不 ++ 的细节真奇妙...

然后就50分了...

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=5e5+,inf=0x3f3f3f3f;
int n,k,L,R,t[xn],lg[xn],f[xn][],id[xn][],bin[],ans;
struct N{
int a,b,l,r;
bool operator < (const N &y) const
{return t[b]-t[a]<t[y.b]-t[y.a];}
};
priority_queue<N>q;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void find(int l,int r,int &y)
{
int g=lg[r-l+];//
r++;//!!!!!
// printf("id[%d][%d]=%d\n",l,g,id[l][g]);
if(t[id[r][g]]<t[id[l+bin[g]][g]])y=id[r][g];
else y=id[l+bin[g]][g];
// printf("find(%d,%d)=%d\n",l,r,y);
}
int main()
{
n=rd(); k=rd(); L=rd(); R=rd();
bin[]=;
for(int i=,x;i<=n;i++)x=rd(),t[i]=t[i-]+x;
for(int i=,p,lst=;i<=n;i++)
{
if(i<lst*)lg[i]=lg[i-];
else lg[i]=lg[i-]+,lst*=,bin[lg[i]]=lst; id[i][]=i-; f[i][]=i-;
for(int j=;j<=;j++)
{
f[i][j]=f[f[i][j-]][j-];
if(t[id[i][j-]]<t[id[f[i][j-]][j-]])id[i][j]=id[i][j-];
else id[i][j]=id[f[i][j-]][j-];
} int l=max(i-R,),r=i-L,len=r-l+;
if(l>r)continue;
find(l,r,p); q.push((N){p,i,l,r});
// printf("ps:%d,%d\n",p,i);
}
int cnt=,p;
while(cnt<k)
{
int a=q.top().a,b=q.top().b,l=q.top().l,r=q.top().r; q.pop();
if(l<=a-)find(l,a-,p),q.push((N){p,b,l,a-})/*,printf("ps:%d,%d\n",p,b)*/;
if(a+<=r)find(a+,r,p),q.push((N){p,b,a+,r})/*,printf("ps:%d,%d\n",p,b)*/;
cnt++; ans+=t[b]-t[a];
// printf("a=%d b=%d\n",a,b);
}
printf("%d\n",ans);
return ;
}

最后发现把 ans 改成 long long 就A了!!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=5e5+,inf=0x3f3f3f3f;
int n,k,L,R,t[xn],lg[xn],f[xn][],id[xn][],bin[];
long long ans;
struct N{
int a,b,l,r;
bool operator < (const N &y) const
{return t[b]-t[a]<t[y.b]-t[y.a];}
};
priority_queue<N>q;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void find(int l,int r,int &y)
{
int g=lg[r-l+];//
r++;//!!!!!
// printf("id[%d][%d]=%d\n",l,g,id[l][g]);
if(t[id[r][g]]<t[id[l+bin[g]][g]])y=id[r][g];
else y=id[l+bin[g]][g];
// printf("find(%d,%d)=%d\n",l,r,y);
}
int main()
{
n=rd(); k=rd(); L=rd(); R=rd();
bin[]=;
for(int i=,x;i<=n;i++)x=rd(),t[i]=t[i-]+x;
for(int i=,p,lst=;i<=n;i++)
{
if(i<lst*)lg[i]=lg[i-];
else lg[i]=lg[i-]+,lst*=,bin[lg[i]]=lst; id[i][]=i-; f[i][]=i-;
for(int j=;j<=;j++)
{
f[i][j]=f[f[i][j-]][j-];
if(t[id[i][j-]]<t[id[f[i][j-]][j-]])id[i][j]=id[i][j-];
else id[i][j]=id[f[i][j-]][j-];
} int l=max(i-R,),r=i-L,len=r-l+;
if(l>r)continue;
find(l,r,p); q.push((N){p,i,l,r});
// printf("ps:%d,%d\n",p,i);
}
int cnt=,p;
while(cnt<k)
{
int a=q.top().a,b=q.top().b,l=q.top().l,r=q.top().r; q.pop();
if(l<=a-)find(l,a-,p),q.push((N){p,b,l,a-})/*,printf("ps:%d,%d\n",p,b)*/;
if(a+<=r)find(a+,r,p),q.push((N){p,b,a+,r})/*,printf("ps:%d,%d\n",p,b)*/;
cnt++; ans+=t[b]-t[a];
// printf("a=%d b=%d\n",a,b);
}
printf("%lld\n",ans);
return ;
}

A

但已经模仿了TJ啦...处理的时候果然要带上自己,不然各种不方便...

别忘了开 long long !因为是多段区间的和!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=5e5+,inf=0x3f3f3f3f;
int n,k,L,R,t[xn],lg[xn],id[xn][];
long long ans;
struct N{
int a,b,l,r;
bool operator < (const N &y) const
{return t[b]-t[a]<t[y.b]-t[y.a];}
};
priority_queue<N>q;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
int mn(int a,int b){return t[a]<t[b]?a:b;}
int find(int l,int r)
{
if(l>r)return -;
int g=lg[r-l+];
return mn(id[l][g],id[r-(<<g)+][g]);
}
int main()
{
n=rd(); k=rd(); L=rd(); R=rd();
for(int i=;i<=n;i++)lg[i]=lg[i>>]+;
for(int i=,x;i<=n;i++)x=rd(),t[i]=t[i-]+x,id[i][]=i;//
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)//0 //-1
id[i][j]=mn(id[i][j-],id[i+(<<(j-))][j-]);
for(int i=L;i<=n;i++)q.push((N){find(max(i-R,),i-L),i,max(i-R,),i-L});
int cnt=,p;
while(cnt<k)
{
int a=q.top().a,b=q.top().b,l=q.top().l,r=q.top().r; q.pop();
cnt++; ans+=t[b]-t[a];
int c=find(l,a-),d=find(a+,r);
if(c!=-)q.push((N){c,b,l,a-});
if(d!=-)q.push((N){d,b,a+,r});
}
printf("%lld\n",ans);
return ;
}

最新文章

  1. NHibernate代码监视
  2. Android源码阅读-Filter过滤器
  3. 【OpenGL(SharpGL)】支持任意相机可平移缩放的轨迹球实现
  4. 线段树区间更新&amp;&amp;求和poj3486
  5. Sql Server 保留几位小数的两种做法
  6. Java跨平台原理
  7. win7 下启动mysql
  8. 翻译【ElasticSearch Server】第一章:开始使用ElasticSearch集群(5)
  9. dl dd dt与ul li
  10. head first c&amp;lt;11&amp;gt;在根据网络编程
  11. USACO Section 1.2 Transformations 解题报告
  12. cmd命令窗口的快速选中复制黏贴
  13. pip 安装 MySQL-python 报错
  14. Codeforces 875F Royal Questions (看题解)
  15. linux中一些简便的命令之tr
  16. 100. Same Tree (Tree;DFS)
  17. golang 本地构建包
  18. CSS实现DIV从隐藏到展示的过渡效果
  19. java进程的守护进程脚本
  20. C++ 使用vector时遇到的一个问题

热门文章

  1. HDU-1858-Max Partial Value I,有坑点,不难;
  2. iOS-runtime-objc_setAssociatedObject(关联对象以及传值)
  3. websocket个人理解总结
  4. Separate code and data contexts: an architectural approach to virtual text sharing
  5. Hashtable和HashMap 的区别
  6. MySql数据库导出csv文件命令
  7. python学习之-- shelve模块
  8. HDU 5883 欧拉路径异或值最大 水题
  9. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown error 1054
  10. js的基础(平民理解的执行上下文/调用堆栈/内存栈/值类型/引用类型)