本蒟蒻连线段树都想着用人品退火解决了......
退火邪教诚不欺我
可是最终提交的时候发现一大堆MLE——
无法接受.jpg
先放上代码:
#pragma GCC opitimize(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<cmath>
#include<ctime>
using namespace std;
#define re register int
#define I_LOVE_YOU cout<<ans<<'\n';//七夕限定
const int N=1e5+5;
const double T=1e3;
const double cool=0.996;
const double mintemp=1e-10;
int n,w,tree[N<<2],ansx,ans;
void add_data(int k,int l,int r,int x,int num)
{
if(l==r)
{
tree[k]+=num;
return;
}
int mid=(l+r)>>1;
if(x<=mid)add_data(k<<1,l,mid,x,num);
else add_data(k<<1|1,mid+1,r,x,num);
tree[k]=tree[k<<1]+tree[k<<1|1];
}
int ask(int k,int l_now,int r_now,int l,int r)
{
if(l>n)return 0;
if(r>n&&l<=n)r=n;
if(l<=l_now&&r_now<=r)return tree[k];
int mid=(l_now+r_now)>>1,res=0;
if(l<=mid)res+=ask(k<<1,l_now,mid,l,r);
if(mid<r)res+=ask(k<<1|1,mid+1,r_now,l,r);
return res;
}
inline void SA()
{
double temp=T;
while(temp>mintemp)
{
double nx;
nx=ansx+(double)(rand()*2-RAND_MAX)*temp;
if(nx<0)continue;
nx=ceil(nx);
// cout<<"nx:"<<nx<<endl;cout<<"temp:"<<temp<<'\n';
int nans=ask(1,1,n,nx,nx+w-1);
int dealt=nans-ans;
if(dealt>0)
{
ansx=nx;
ans=nans;
}
else if(exp((double)dealt/temp)>rand())ansx=nx;
temp*=cool;
}
}
int main()
{
srand(time(NULL));srand(rand());
ios::sync_with_stdio(false);
memset(tree,0,sizeof(tree));
cin>>n>>w;
if(!w)
{
I_LOVE_YOU
return 0;
}
for(re i=1;i<=n;++i)
{
int x,b;
cin>>x>>b;
add_data(1,1,n,x,b);
}
ansx=1;
ans=ask(1,1,n,ansx,ansx+w-1);
while((double)clock()/CLOCKS_PER_SEC<0.8)SA();
I_LOVE_YOU
return 0;
}
我发现线段树内部应该没有问题,删去退火里边的
int nans=ask(1,1,n,nx,nx+w-1);
就不会MLE了
为什么呢???求解