# [Snoi2017]炸弹

### 题目相关

BZOJ的题目链接：https://www.lydsy.com/JudgeOnline/problem.php?id=5017
LOJ的数据下载链接：https://loj.ac/problem/2255/testdata

### 解法

#### 算法2

#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
#define rg register
typedef long long LL;
template <typename T> inline T max(const T a,const T b){return a>b?a:b;}
template <typename T> inline T min(const T a,const T b){return a<b?a:b;}
template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;}
template <typename T> inline void maxd(T&a,const T b){a=a>b?a:b;}
template <typename T> inline T abs(const T a){return a>0?a:-a;}
template <typename T> inline void swap(T&a,T&b){T c=a;a=b;b=c;}
template <typename T> inline T gcd(const T a,const T b){if(!b)return a;return gcd(b,a%b);}
template <typename T> inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T> inline T square(const T x){return x*x;};
template <typename T> inline void read(T&x)
{
char cu=getchar();x=0;bool fla=0;
while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}
while(isdigit(cu))x=x*10+cu-'0',cu=getchar();
if(fla)x=-x;
}
template <typename T> void printe(const T x)
{
if(x>=10)printe(x/10);
putchar(x%10+'0');
}
template <typename T> inline void print(const T x)
{
if(x<0)putchar('-'),printe(-x);
else printe(x);
}
const int maxn=500003,maxm=1000003;
int n,Stack[maxn],Top;
LL x[maxn],l[maxn],r[maxn];
int belo[maxn],n_d,MIN[maxn],MAX[maxn];
int stack[maxn],top;
inline void addb(const int u,const int v)
{
tmp++;
tow[tmp]=v;
}
int tot,DFN[maxn],LOW[maxn];
int beg;
inline void push(const int x){stack[++top]=x;}
inline int pop(){return stack[top--];}
void DFS(int u)
{
DFN[u]=LOW[u]=++tot;
push(u);
{
const int v=tow[i];
if(!DFN[v])DFS(v),mind(LOW[u],LOW[v]);
else if(belo[v]==0)mind(LOW[u],DFN[v]);
}
if(LOW[u]==DFN[u])
{
n_d++;
int cl=pop();
MIN[n_d]=cl,MAX[n_d]=cl,belo[cl]=n_d;
while(cl!=u)cl=pop(),mind(MIN[n_d],cl),maxd(MAX[n_d],cl),belo[cl]=n_d;
}
}
inline void addb_d(const int u,const int v)
{
if(u==v)return;
}
int dp[maxn];
int mini[maxn],maxi[maxn];
void draw()
{
for(rg int i=1;i<=n;i++)
}
const LL mod=1000000007;
LL res;LL ans[maxn];
void calc(const int u)
{
dp[u]=0;
mini[u]=MIN[u],maxi[u]=MAX[u];
{
const int v=tow_d[i];
if(dp[v]==-1)calc(v);
mind(mini[u],mini[v]),maxd(maxi[u],maxi[v]);
}
ans[u]=maxi[u]-mini[u]+1;
}
int main()
for(rg int i=1;i<=n;i++)
{
l[i]=std::lower_bound(x+1,x+n+1,x[i]-r[i])-x;
r[i]=std::upper_bound(x+1,x+n+1,x[i]+r[i])-x-1;
}
for(rg int i=1;i<=n;i++)
{
while(Top&&r[Stack[Top]]<i)Top--;
Stack[++Top]=i;
}
Top=0;
for(rg int i=n;i>=1;i--)
{
while(Top&&l[Stack[Top]]>i)Top--;
Stack[++Top]=i;
}
for(beg=1;beg<=n;beg++)if(!DFN[beg])DFS(beg);
draw();
memset(dp,-1,sizeof(dp));
for(rg int i=1;i<=n_d;i++)if(dp[i]==-1)calc(i);
for(rg int i=1;i<=n;i++)res=(res+(LL)i*ans[belo[i]])%mod;
print(res);
return 0;
}


#### 算法3（搬自https://blog.csdn.net/C_K_Y_/article/details/79980119）（假算法）

5
1 0
30 100
50 20
90 0
100 0


4
60 0
90 20
100 10
110 50


（我一开始测了这个算法这个数据，发现过了，bzoj上也AC了，觉得真是很优越，然后最后却被告知这是一个假算法，深深感受到自己看别人的算法严谨性不足）