A HDU - 4333
https://cn.vjudge.net/problem/30656/origin
扩展Kmp
先翻倍原串s1得到s2
再用exkmp求s2的后缀跟s1的LCP
假如ex[i]>=len说明相等
< len则判断下一位的大小关系
需要注意判断循环节
假如是有循环节的那么需要整体除掉循环次数
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <queue>
#include <cstdio>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <cstring>
#include <cmath>
#include <vector>
#include <ctime>
#include <bitset>
#include <assert.h>
using namespace std;
#define pb push_back
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define ansn() printf("%d\n",ans)
#define lansn() printf("%lld\n",ans)
#define r0(i,n) for(int i=0;i<(n);++i)
#define r1(i,e) for(int i=1;i<=e;++i)
#define rn(i,e) for(int i=e;i>=1;--i)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define lowbit(a) (a&(-a))
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp(aa,bb) make_pair(aa,bb)
#define lrt rt<<1
#define rrt rt<<1|1
#define X first
#define Y second
#define PI (acos(-1.0))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
//const ll mod = 1000000007;
const double eps=1e-12;
const int inf=0x3f3f3f3f;
//const ll infl = 100000000000000000;//1e17
const int maxn= 2e6+20;
const int maxm = 5e3+20;
//muv[i]=(p-(p/i))*muv[p%i]%p;
int in(int &ret) {
char c;
int sgn ;
if(c=getchar(),c==EOF)return -1;
while(c!='-'&&(c<'0'||c>'9'))c=getchar();
sgn = (c=='-')?-1:1;
ret = (c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9')ret = ret*10+(c-'0');
ret *=sgn;
return 1;
}
int nt[200005];
int ex[200005];
char s[200005];
char s2[200005];
void kmp(char x[],int m)
{
int i ,j;
j = nt[0] = -1;
i = 0;
while(i<m)
{
while(j!=-1&&x[i]!=x[j])j = nt[j];
nt[++i] = ++j;
}
}
void pre(char x[],int m) {
nt[0] = m;
int j = 0;
while(j+1<m&&x[j]==x[j+1])++j;
nt[1] = j;
int k = 1;
for(int i=2; i<m; ++i) {
int p = nt[k] + k - 1;
int l = nt[i-k];
if(i+l<p+1)nt[i] = l;
else {
j = max(0,p-i+1);
while(i+j<m&&x[i+j]==x[j])++j;
nt[i] = j;
k = i;
}
}
}
void exkmp(char x[],int m,char y[],int n) {
pre(x,m);
int j = 0;
while(j<n&&j<m&&x[j]==y[j])++j;
ex[0] = j;
int k = 0;
for(int i=1; i<n; ++i) {
int p = ex[k] + k -1;
int l = nt[i-k];
if(i+l<p+1)ex[i] = l;
else {
j = max(0,p-i+1);
while(i+j<n&&j<m&&y[i+j]==x[j])++j;
ex[i] = j;
k = i;
}
}
}
int main() {
#ifdef LOCAL
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif // LOCAL
int t;
sd(t);
r1(cas,t) {
printf("Case %d: ",cas);
ss(s);
int n = strlen(s);
kmp(s,n);
int re = n - nt[n];
if(n%re==0)re = n/re;
else re = 1;
for(int i=0; i<2*n; ++i)
if(i<n)s2[i] = s[i];
else s2[i] = s[i-n];
exkmp(s,n,s2,2*n);
int a,b,c;
a = b = c = 0;
for(int i=0;i<n;++i)
{
if(ex[i]>=n)++b;
else if(s2[i+ex[i]]<s2[ex[i]])++a;
else ++c;
}
a/=re,b/=re,c/=re;
printf("%d %d %d",a,b,c);
puts("");
}
return 0;
}
B HDU - 2817
https://cn.vjudge.net/problem/17937/origin
直接判断是等差还是等比
等比需要qpow
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <queue>
#include <cstdio>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <cstring>
#include <cmath>
#include <vector>
#include <ctime>
#include <bitset>
#include <assert.h>
using namespace std;
#define pb push_back
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define ansn() printf("%d\n",ans)
#define lansn() printf("%lld\n",ans)
#define r0(i,n) for(int i=0;i<(n);++i)
#define r1(i,e) for(int i=1;i<=e;++i)
#define rn(i,e) for(int i=e;i>=1;--i)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define lowbit(a) (a&(-a))
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp(aa,bb) make_pair(aa,bb)
#define lrt rt<<1
#define rrt rt<<1|1
#define X first
#define Y second
#define PI (acos(-1.0))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
//const ll mod = 1000000007;
//const ll mod = 1000000007;
const double eps=1e-12;
const int inf=0x3f3f3f3f;
//const ll infl = 100000000000000000;//1e17
const int maxn= 1e5+20;
const int maxm = 2e3+20;
//muv[i]=(p-(p/i))*muv[p%i]%p;
int in(int &ret) {
char c;
int sgn ;
if(c=getchar(),c==EOF)return -1;
while(c!='-'&&(c<'0'||c>'9'))c=getchar();
sgn = (c=='-')?-1:1;
ret = (c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9')ret = ret*10+(c-'0');
ret *=sgn;
return 1;
}
ll a[20];
ll mod = 200907;
ll qpow(ll x,ll k)
{
ll r = 1;
while(k)
{
if(k&1)r = r*x%mod;
x = x*x%mod;
k>>=1;
}
return r;
}
int main() {
#ifdef LOCAL
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif // LOCAL
int T;
in(T);
r1(i,T) {
// printf("Case #%d: ",i);
r1(i,3)sld(a[i]);
ll k;
sld(k);
if(a[2]-a[1]==a[3]-a[2])
{
ll x = a[2]-a[1];
x%=mod;
ll ans = a[1]%200907 + ((k-1)%mod)*x%mod;
ans %= mod;
lansn();
}
else if(a[2]/a[1]==a[3]/a[2])
{
ll x = a[2]/a[1];
x%=mod;
ll ans = a[1]%mod;
ans = ans * qpow(x,k-1)%mod;
lansn();
}
}
return 0;
}
C HDU - 3564
https://cn.vjudge.net/problem/11614/origin
按顺序插入数字i问每次插入后的LIS
因为是按升序插的 所以先求出最终序列 对每个数字结尾求出LIS
再做一个前缀最大值
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <queue>
#include <cstdio>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <cstring>
#include <cmath>
#include <vector>
#include <ctime>
#include <bitset>
#include <assert.h>
using namespace std;
#define pb push_back
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define ansn() printf("%d\n",ans)
#define lansn() printf("%lld\n",ans)
#define r0(i,n) for(int i=0;i<(n);++i)
#define r1(i,e) for(int i=1;i<=e;++i)
#define rn(i,e) for(int i=e;i>=1;--i)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define lowbit(a) (a&(-a))
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp(aa,bb) make_pair(aa,bb)
#define lrt rt<<1
#define rrt rt<<1|1
#define X first
#define Y second
#define PI (acos(-1.0))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
//const ll mod = 1000000007;
const double eps=1e-12;
const int inf=0x3f3f3f3f;
//const ll infl = 100000000000000000;//1e17
const int maxn= 2e6+20;
const int maxm = 5e3+20;
//muv[i]=(p-(p/i))*muv[p%i]%p;
int in(int &ret) {
char c;
int sgn ;
if(c=getchar(),c==EOF)return -1;
while(c!='-'&&(c<'0'||c>'9'))c=getchar();
sgn = (c=='-')?-1:1;
ret = (c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9')ret = ret*10+(c-'0');
ret *=sgn;
return 1;
}
int bit[100005];
void update(int x,int v) {
while(x<100005) {
bit[x]+=v;
x+=lowbit(x);
}
}
int query(int x) {
int r = 0;
while(x) {
r+=bit[x];
x-=lowbit(x);
}
return r;
}
int a[100005];
int b[100005];
int c[100005];
int main() {
#ifdef LOCAL
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif // LOCAL
int t;
sd(t);
r1(cas,t) {
printf("Case #%d:\n",cas);
int n;
sd(n);
r1(i,n)bit[i] = 0;
r1(i,n)sd(a[i]),update(i,1);
rn(i,n) {
int p = a[i]+1;
int l = 1,r = n;
int can = 0;
while(l<=r) {
int mid = (l+r)>>1;
int q = query(mid);
if(q>=p)can = mid,r = mid-1;
else l = mid+1;
}
b[can] = i;
update(can,-1);
}
// r1(i,n)printf("%d%c",b[i]," \n"[i==n]);
int len = 1;
a[len] = b[1];
c[b[1]] = 1;
for(int i=2; i<=n; ++i) {
if(b[i]>a[len])a[++len] = b[i],c[b[i]] = len;
else {
int l = 1,r = len;
int p = 0;
while(l<=r) {
int mid = (l+r)>>1;
if(b[i]<a[mid])p = mid,r = mid - 1;
else l = mid+1;
}
a[p] = b[i];
c[b[i]] = p;
}
}
r1(i,n)c[i] = max(c[i],c[i-1]);
r1(i,n) {
int ans = c[i];
ansn();
}
puts("");
}
return 0;
}
D HDU - 3980
https://cn.vjudge.net/problem/22747/origin
SG函数
需要注意状态如果会同时到2个是需要异或起来的
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <queue>
#include <cstdio>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <cstring>
#include <cmath>
#include <vector>
#include <ctime>
#include <bitset>
#include <assert.h>
using namespace std;
#define pb push_back
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define ansn() printf("%d\n",ans)
#define lansn() printf("%lld\n",ans)
#define r0(i,n) for(int i=0;i<(n);++i)
#define r1(i,e) for(int i=1;i<=e;++i)
#define rn(i,e) for(int i=e;i>=1;--i)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define lowbit(a) (a&(-a))
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp(aa,bb) make_pair(aa,bb)
#define lrt rt<<1
#define rrt rt<<1|1
#define X first
#define Y second
#define PI (acos(-1.0))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
//const ll mod = 1000000007;
const double eps=1e-12;
const int inf=0x3f3f3f3f;
//const ll infl = 100000000000000000;//1e17
const int maxn= 2e6+20;
const int maxm = 5e3+20;
//muv[i]=(p-(p/i))*muv[p%i]%p;
int in(int &ret) {
char c;
int sgn ;
if(c=getchar(),c==EOF)return -1;
while(c!='-'&&(c<'0'||c>'9'))c=getchar();
sgn = (c=='-')?-1:1;
ret = (c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9')ret = ret*10+(c-'0');
ret *=sgn;
return 1;
}
bool vis[maxn];
int sg[maxn];
int m;
int get(int x) {
vector<int>v;
for(int j=0; x - m - j>=0; ++j) {
int y = sg[j]^sg[x-j-m];
if(!vis[y])vis[y] = 1,v.pb(y);
}
int r = -1;
for(int j=0;; ++j)if(!vis[j]) {
r = j;
break;
}
int sz = v.size();
r0(i,sz) {
int y = v[i];
vis[y] = 0;
}
return r;
}
int main() {
#ifdef LOCAL
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif // LOCAL
int t;
sd(t);
r1(cas,t) {
printf("Case #%d: ",cas);
int n;
sdd(n,m);
if(n<m)
{
puts("abcdxyzk");
continue;
}
r0(i,m)sg[i] = 0;
for(int i=m; i<=n-m; ++i)sg[i] = get(i);
puts(sg[n-m]?"abcdxyzk":"aekdycoin");
}
return 0;
}
E HDU - 4389
https://cn.vjudge.net/problem/31553/origin
求[L,R]之间的i%f(i)==0的个数
数位dp
dp i j k l 表示 i 位 l为f(i) j为当前总和 k为当前总和%l的个数
我是分段打表过的 所以没有代码
F HDU - 4861
https://cn.vjudge.net/problem/51987/origin
打表可以发现有神秘的规律
ll k,p;
while(~sldd(k,p))
{
if((k/(p-1))&1)puts("YES");
else puts("NO");
}
G HDU - 4871
https://cn.vjudge.net/problem/51986/origin
树的点分治
对每个root统计经过这个root的路径
做一个dp
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <queue>
#include <cstdio>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <cstring>
#include <cmath>
#include <vector>
#include <ctime>
#include <bitset>
#include <assert.h>
using namespace std;
#define pb push_back
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define ansn() printf("%d\n",ans)
#define lansn() printf("%lld\n",ans)
#define r0(i,n) for(int i=0;i<(n);++i)
#define r1(i,e) for(int i=1;i<=e;++i)
#define rn(i,e) for(int i=e;i>=1;--i)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define lowbit(a) (a&(-a))
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp(aa,bb) make_pair(aa,bb)
#define lrt rt<<1
#define rrt rt<<1|1
#define X first
#define Y second
#define PI (acos(-1.0))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
//const ll mod = 1000000007;
const double eps=1e-12;
const int inf=0x3f3f3f3f;
//const ll infl = 100000000000000000;//1e17
const int maxn= 2e6+20;
const int maxm = 5e3+20;
//muv[i]=(p-(p/i))*muv[p%i]%p;
int in(int &ret) {
char c;
int sgn ;
if(c=getchar(),c==EOF)return -1;
while(c!='-'&&(c<'0'||c>'9'))c=getchar();
sgn = (c=='-')?-1:1;
ret = (c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9')ret = ret*10+(c-'0');
ret *=sgn;
return 1;
}
struct node {
int to,nt,w;
node() {}
node(int a,int b,int c) {
to = a,nt = b;
w = c;
}
} edge[60005];
int tot;
bool vis[30005];
int head[30005];
int a[60005],b[60005],c[60005];
void addedge(int u,int v,int w) {
edge[tot] = node(v,head[u],w);
head[u] = tot++;
}
vector< pair<pii,int> >g[30005];
int dis[30005];
int edid[30005];
void dij(int n) {
for(int i=1; i<=n; ++i)sort(all(g[i]));
for(int i=1; i<=n; ++i)dis[i] = inf,vis[i] = 0;
dis[1] = 0;
priority_queue<pii>q;
q.push(mp(-0,1));
while(!q.empty()) {
pii p = q.top();
q.pop();
int u = p.Y;
if(vis[u])continue;
vis[u] = 1;
int sz = g[u].size();
r0(i,sz) {
int v = g[u][i].X.X;
int w = g[u][i].X.Y;
int id = g[u][i].Y;
if(dis[v]>dis[u]+w) {
dis[v] = dis[u] + w;
edid[v] = id;
q.push(mp(-dis[v],v));
}
}
}
}
void con(int n) {
for(int i=1;i<=n;++i)head[i] = -1,vis[i] = 0;
tot = 0;
for(int i=2; i<=n; ++i) {
int id = edid[i];
addedge(a[id],b[id],c[id]);
addedge(b[id],a[id],c[id]);
}
}
int mxson[30005];
int sz[30005];
void dfssize(int u,int f) {
sz[u] = 1;
mxson[u] = 0;
for(int i=head[u]; ~i; i = edge[i].nt) {
int v = edge[i].to;
if(v==f||vis[v])continue;
dfssize(v,u);
sz[u] += sz[v];
mxson[u] = max(mxson[u],sz[v]);
}
}
int rt;
void dfsroot(int rtt,int u,int f) {
mxson[u] = max(mxson[u],sz[rtt] - sz[u]);
if(mxson[rt]>mxson[u])
rt = u;
for(int i=head[u]; ~i; i = edge[i].nt) {
int v = edge[i].to;
if(v==f||vis[v])continue;
dfsroot(rtt,v,u);
}
}
int k;
int ans;
ll ct;
int mxl;
int dp[30005];
int num[30005];
pii use[30005];
int cnt;
void dfslen(int u,int f,int now,int len) {
mxl = max(mxl,len);
use[cnt++] = mp(now,len);
if(k-len-1>=0&&dp[k-len-1]!=-1&&ans<now+dp[k-len-1])
ans = now + dp[k-len-1],ct = 0;
if(k-len-1>=0&&dp[k-len-1]!=-1&&ans==now+dp[k-len-1])
ct += num[k-len-1];
for(int i=head[u]; ~i; i = edge[i].nt) {
int v = edge[i].to,w = edge[i].w;
if(v==f||vis[v])continue;
dfslen(v,u,now+w,len+1);
}
}
void cal(int u) {
mxl = 0;
dp[0] = 0;
num[0] = 1;
for(int i=head[u]; ~i; i = edge[i].nt) {
cnt = 0;
int v = edge[i].to;
int w = edge[i].w;
if(vis[v])continue;
dfslen(v,u,w,1);
for(int j=0; j<cnt; ++j) {
int now = use[j].X;
int len = use[j].Y;
if(dp[len]<now) {
dp[len] = now;
num[len] = 0;
}
if(dp[len]==now)++num[len];
}
}
for(int i=0; i<=mxl; ++i)dp[i]= -1,num[i] = 0;
}
void dfs(int u,int n) {
dfssize(u,0);
rt = 0;
mxson[0] = n;
dfsroot(u,u,0);
cal(rt);
vis[rt] = 1;
for(int i=head[rt]; ~i; i = edge[i].nt) {
int v = edge[i].to;
if(vis[v])continue;
dfs(v,n);
}
}
int main() {
#ifdef LOCAL
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif // LOCAL
int t;
sd(t);
while(t--) {
int n,m;
sddd(n,m,k);
r1(i,n)g[i].clear();
r1(i,m) {
sddd(a[i],b[i],c[i]);
int u = a[i],v = b[i];
g[u].pb(mp(mp(v,c[i]),i));
g[v].pb(mp(mp(u,c[i]),i));
}
for(int i=1; i<=n; ++i)dp[i] = -1;
dij(n);
con(n);
ans = 0;
ct = 0;
dfs(1,n);
printf("%d %lld\n",ans,ct);
}
return 0;
}
H 51Nod - 1091
https://cn.vjudge.net/problem/739982/origin
X轴上有N条线段,每条线段包括1个起点和终点。线段的重叠是这样来算的,10201020和12251225的重叠部分为12201220。
给出N条线段的起点和终点,从中选出2条线段,这两条线段的重叠部分是最长的。输出这个最长的距离。如果没有重叠,输出0。
l,r排个序
用个优先队列维护一下当前还没走过的线段的右端点
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <queue>
#include <cstdio>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <cstring>
#include <cmath>
#include <vector>
#include <ctime>
#include <bitset>
#include <assert.h>
using namespace std;
#define pb push_back
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define ansn() printf("%d\n",ans)
#define lansn() printf("%lld\n",ans)
#define r0(i,n) for(int i=0;i<(n);++i)
#define r1(i,e) for(int i=1;i<=e;++i)
#define rn(i,e) for(int i=e;i>=1;--i)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define lowbit(a) (a&(-a))
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp(aa,bb) make_pair(aa,bb)
#define lrt rt<<1
#define rrt rt<<1|1
#define X first
#define Y second
#define PI (acos(-1.0))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
//const ll mod = 1000000007;
//const ll mod = 1000000007;
const double eps=1e-12;
const int inf=0x3f3f3f3f;
//const ll infl = 100000000000000000;//1e17
const int maxn= 5e4+20;
const int maxm = 2e3+20;
//muv[i]=(p-(p/i))*muv[p%i]%p;
int in(int &ret) {
char c;
int sgn ;
if(c=getchar(),c==EOF)return -1;
while(c!='-'&&(c<'0'||c>'9'))c=getchar();
sgn = (c=='-')?-1:1;
ret = (c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9')ret = ret*10+(c-'0');
ret *=sgn;
return 1;
}
struct node
{
int l,r;
bool operator <(const node &o)const
{
if(l!=o.l)return l<o.l;
return r>o.r;
}
}no[maxn];
int main() {
#ifdef LOCAL
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif // LOCAL
// int T;
// in(T);
// r1(i,T) {
//
// }
int n;
sd(n);
r1(i,n)sdd(no[i].l,no[i].r);
sort(no+1,no+1+n);
priority_queue<pii>q;
int ans = 0;
r1(i,n)
{
int ul = no[i].l,ur = no[i].r;
while(!q.empty())
{
pii p = q.top();
int l = p.Y,r = p.X;
if(r<ul)q.pop();
else break;
}
if(!q.empty())
{
pii p = q.top();
int r = p.X;
int rr = min(ur,r);
ans = max(ans,rr - ul);
}
q.push(mp(ur,ul));
}
ansn();
return 0;
}