Diff
checker
Texto
Texto
Imagens
Documentos
Excel
Pastas
Legal
Enterprise
Aplicativo para desktop
Preços
Fazer login
Baixar o Diffchecker Desktop
Comparar texto
Encontre a diferença entre dois arquivos de texto
Ferramentas
Histórico
Editor live
Recolher inalteradas
Sem quebra de linha
Layout
Dividido
Unificado
Nível de detalhe
Inteligente
Palavra
Caractere
Realce de sintaxe
Escolher sintaxe
Ignorar
Transformar texto
Ir à primeira mudança
Editar entrada
Diffchecker Desktop
A maneira mais segura de usar o Diffchecker. Obtenha o aplicativo Diffchecker Desktop: seus diffs nunca saem do seu computador!
Obter Desktop
「USACO 2020.12 Platinum」Cowmistry
Criado
há 2 anos
O diff nunca expira
Limpar
Exportar
Compartilhar
Os dois textos são idênticos
Não há diferença entre estes dois textos
0 remoções
Linhas
Total
Removido
Caracteres
Total
Removido
Para continuar usando este recurso, atualize para
Diff
checker
Pro
Ver preços
113 linhas
Copiar tudo
0 adições
Linhas
Total
Adicionado
Caracteres
Total
Adicionado
Para continuar usando este recurso, atualize para
Diff
checker
Pro
Ver preços
113 linhas
Copiar tudo
#include<bits/stdc++.h>
#include<bits/stdc++.h>
using namespace std;
using namespace std;
typedef long long ll;
typedef long long ll;
typedef pair <int,int> Pii;
typedef pair <int,int> Pii;
#define mp make_pair
#define mp make_pair
#define pb push_back
#define pb push_back
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
char IO;
char IO;
int rd(){
int rd(){
int s=0;
int s=0;
while(!isdigit(IO=getchar()));
while(!isdigit(IO=getchar()));
do s=(s<<1)+(s<<3)+(IO^'0');
do s=(s<<1)+(s<<3)+(IO^'0');
while(isdigit(IO=getchar()));
while(isdigit(IO=getchar()));
return s;
return s;
}
}
const int N=2e4+10,P=1e9+7,I2=(P+1)/2,I3=(P+1)/3,U=1<<30;
const int N=2e4+10,P=1e9+7,I2=(P+1)/2,I3=(P+1)/3,U=1<<30;
int n,m,k;
int n,m,k;
int L[N],R[N];
int L[N],R[N];
int Check(){
int Check(){
for(int i=k;i;i>>=1) if(~i&1) return 0;
for(int i=k;i;i>>=1) if(~i&1) return 0;
return 1;
return 1;
}
}
int D3(int n){ return 1ll*n*(n-1)/2%P*(n-2)%P*I3%P; }
int D3(int n){ return 1ll*n*(n-1)/2%P*(n-2)%P*I3%P; }
int D2(int n){ return 1ll*n*(n-1)/2%P; }
int D2(int n){ return 1ll*n*(n-1)/2%P; }
const int M=N*60;
const int M=N*60;
int s[M],ls[M],rs[M],t[M],cnt,rt;
int s[M],ls[M],rs[M],t[M],cnt,rt;
//在线段树上插入节点,打上标记,同时处理出size便于下面计算
//在线段树上插入节点,打上标记,同时处理出size便于下面计算
void Ins(int &p,int l,int r,int ql,int qr){
void Ins(int &p,int l,int r,int ql,int qr){
if(!p) p=++cnt;
if(!p) p=++cnt;
s[p]+=min(qr,r)-max(ql,l)+1;
s[p]+=min(qr,r)-max(ql,l)+1;
if(ql<=l && r<=qr) { t[p]=1; return; }
if(ql<=l && r<=qr) { t[p]=1; return; }
int mid=(l+r)>>1;
int mid=(l+r)>>1;
if(ql<=mid) Ins(ls[p],l,mid,ql,qr);
if(ql<=mid) Ins(ls[p],l,mid,ql,qr);
if(qr>mid) Ins(rs[p],mid+1,r,ql,qr);
if(qr>mid) Ins(rs[p],mid+1,r,ql,qr);
}
}
int ans;
int ans;
// O(1)求出m
// O(1)求出m
int Up(int k){ return 1<<(32-__builtin_clz(k)); }
int Up(int k){ return 1<<(32-__builtin_clz(k)); }
typedef vector <Pii> V;
typedef vector <Pii> V;
V Union(const V &A,const V &B){
V Union(const V &A,const V &B){
int p1=0,p2=0,s1=A.size(),s2=B.size();
int p1=0,p2=0,s1=A.size(),s2=B.size();
V R;
V R;
// 这里是否归并并不影响复杂度
// 这里是否归并并不影响复杂度
while(p1<s1 || p2<s2) {
while(p1<s1 || p2<s2) {
if(p1<s1 && (p2==s2||A[p1]<B[p2])) {
if(p1<s1 && (p2==s2||A[p1]<B[p2])) {
if(R.size() && R.back().first==A[p1].first) R.back().second+=A[p1].second;
if(R.size() && R.back().first==A[p1].first) R.back().second+=A[p1].second;
else R.pb(A[p1]);
else R.pb(A[p1]);
p1++;
p1++;
} else {
} else {
if(R.size() && R.back().first==B[p2].first) R.back().second+=B[p2].second;
if(R.size() && R.back().first==B[p2].first) R.back().second+=B[p2].second;
else R.pb(B[p2]);
else R.pb(B[p2]);
p2++;
p2++;
}
}
}
}
return R;
return R;
}
}
V Calc(int a,int b,int L,int k,int f1,int f2){
V Calc(int a,int b,int L,int k,int f1,int f2){
f1|=t[a],f2|=t[b];
f1|=t[a],f2|=t[b];
V Res;
V Res;
// 底层情况O(1)解决
// 底层情况O(1)解决
if(!f1 && !a) return Res;
if(!f1 && !a) return Res;
if(f2) return Res.pb(mp(k+1,f1?L:s[a])),Res;
if(f2) return Res.pb(mp(k+1,f1?L:s[a])),Res;
if(!b) return Res.pb(mp(0,f1?L:s[a])),Res;
if(!b) return Res.pb(mp(0,f1?L:s[a])),Res;
int m=Up(k);
int m=Up(k);
// L>m说明还要继续进行分裂
// L>m说明还要继续进行分裂
if(L>m) return Union(Calc(ls[a],ls[b],L/2,k,f1,f2),Calc(rs[a],rs[b],L/2,k,f1,f2));
if(L>m) return Union(Calc(ls[a],ls[b],L/2,k,f1,f2),Calc(rs[a],rs[b],L/2,k,f1,f2));
// 进入降阶子问题,左查右,右查左
// 进入降阶子问题,左查右,右查左
k-=m/2;
k-=m/2;
V A=Calc(ls[a],rs[b],L/2,k,f1,f2);
V A=Calc(ls[a],rs[b],L/2,k,f1,f2);
for(auto &i:A) i.first+=f2?L/2:s[ls[b]];
for(auto &i:A) i.first+=f2?L/2:s[ls[b]];
V B=Calc(rs[a],ls[b],L/2,k,f1,f2);
V B=Calc(rs[a],ls[b],L/2,k,f1,f2);
for(auto &i:B) i.first+=f2?L/2:s[rs[b]];
for(auto &i:B) i.first+=f2?L/2:s[rs[b]];
return Union(A,B);
return Union(A,B);
}
}
int cm;
int cm;
// 第一次分裂
// 第一次分裂
void Solve(int p,int L){
void Solve(int p,int L){
if(!p) return;
if(!p) return;
// 完全覆盖的部分答案可以快速求出
// 完全覆盖的部分答案可以快速求出
if(t[p]) { cm+=L/m; return; }
if(t[p]) { cm+=L/m; return; }
// 已经完成分裂,此时进入第一层子问题
// 已经完成分裂,此时进入第一层子问题
if(L==m) {
if(L==m) {
// 贡献分为
// 贡献分为
// 左选3 , 右选 3
// 左选3 , 右选 3
ans=(ans+D3(s[ls[p]]))%P,ans=(ans+D3(s[rs[p]]))%P;
ans=(ans+D3(s[ls[p]]))%P,ans=(ans+D3(s[rs[p]]))%P;
// 左1,右2
// 左1,右2
V A=Calc(ls[p],rs[p],m/2,k-m/2,0,0);
V A=Calc(ls[p],rs[p],m/2,k-m/2,0,0);
// 左2,右1
// 左2,右1
V B=Calc(rs[p],ls[p],m/2,k-m/2,0,0);
V B=Calc(rs[p],ls[p],m/2,k-m/2,0,0);
for(auto i:A) ans=(ans+1ll*D2(i.first)*i.second)%P;
for(auto i:A) ans=(ans+1ll*D2(i.first)*i.second)%P;
for(auto i:B) ans=(ans+1ll*D2(i.first)*i.second)%P;
for(auto i:B) ans=(ans+1ll*D2(i.first)*i.second)%P;
return;
return;
}
}
Solve(ls[p],L/2),Solve(rs[p],L/2);
Solve(ls[p],L/2),Solve(rs[p],L/2);
}
}
int main(){
int main(){
n=rd(),k=rd();
n=rd(),k=rd();
rep(i,1,n) { int l=rd(),r=rd(); Ins(rt,0,U-1,l,r); }
rep(i,1,n) { int l=rd(),r=rd(); Ins(rt,0,U-1,l,r); }
m=Up(k),Solve(rt,U);
m=Up(k),Solve(rt,U);
// O(1)求得完全覆盖部分的答案
// O(1)求得完全覆盖部分的答案
int t=(2ll*D3(m/2)+1ll*D2(k-m/2+1)*m)%P;
int t=(2ll*D3(m/2)+1ll*D2(k-m/2+1)*m)%P;
ans=(ans+1ll*cm*t)%P;
ans=(ans+1ll*cm*t)%P;
printf("%d\n",ans);
printf("%d\n",ans);
}
}
Diferenças salvas
Texto original
Abrir arquivo
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair <int,int> Pii; #define mp make_pair #define pb push_back #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i) char IO; int rd(){ int s=0; while(!isdigit(IO=getchar())); do s=(s<<1)+(s<<3)+(IO^'0'); while(isdigit(IO=getchar())); return s; } const int N=2e4+10,P=1e9+7,I2=(P+1)/2,I3=(P+1)/3,U=1<<30; int n,m,k; int L[N],R[N]; int Check(){ for(int i=k;i;i>>=1) if(~i&1) return 0; return 1; } int D3(int n){ return 1ll*n*(n-1)/2%P*(n-2)%P*I3%P; } int D2(int n){ return 1ll*n*(n-1)/2%P; } const int M=N*60; int s[M],ls[M],rs[M],t[M],cnt,rt; //在线段树上插入节点,打上标记,同时处理出size便于下面计算 void Ins(int &p,int l,int r,int ql,int qr){ if(!p) p=++cnt; s[p]+=min(qr,r)-max(ql,l)+1; if(ql<=l && r<=qr) { t[p]=1; return; } int mid=(l+r)>>1; if(ql<=mid) Ins(ls[p],l,mid,ql,qr); if(qr>mid) Ins(rs[p],mid+1,r,ql,qr); } int ans; // O(1)求出m int Up(int k){ return 1<<(32-__builtin_clz(k)); } typedef vector <Pii> V; V Union(const V &A,const V &B){ int p1=0,p2=0,s1=A.size(),s2=B.size(); V R; // 这里是否归并并不影响复杂度 while(p1<s1 || p2<s2) { if(p1<s1 && (p2==s2||A[p1]<B[p2])) { if(R.size() && R.back().first==A[p1].first) R.back().second+=A[p1].second; else R.pb(A[p1]); p1++; } else { if(R.size() && R.back().first==B[p2].first) R.back().second+=B[p2].second; else R.pb(B[p2]); p2++; } } return R; } V Calc(int a,int b,int L,int k,int f1,int f2){ f1|=t[a],f2|=t[b]; V Res; // 底层情况O(1)解决 if(!f1 && !a) return Res; if(f2) return Res.pb(mp(k+1,f1?L:s[a])),Res; if(!b) return Res.pb(mp(0,f1?L:s[a])),Res; int m=Up(k); // L>m说明还要继续进行分裂 if(L>m) return Union(Calc(ls[a],ls[b],L/2,k,f1,f2),Calc(rs[a],rs[b],L/2,k,f1,f2)); // 进入降阶子问题,左查右,右查左 k-=m/2; V A=Calc(ls[a],rs[b],L/2,k,f1,f2); for(auto &i:A) i.first+=f2?L/2:s[ls[b]]; V B=Calc(rs[a],ls[b],L/2,k,f1,f2); for(auto &i:B) i.first+=f2?L/2:s[rs[b]]; return Union(A,B); } int cm; // 第一次分裂 void Solve(int p,int L){ if(!p) return; // 完全覆盖的部分答案可以快速求出 if(t[p]) { cm+=L/m; return; } // 已经完成分裂,此时进入第一层子问题 if(L==m) { // 贡献分为 // 左选3 , 右选 3 ans=(ans+D3(s[ls[p]]))%P,ans=(ans+D3(s[rs[p]]))%P; // 左1,右2 V A=Calc(ls[p],rs[p],m/2,k-m/2,0,0); // 左2,右1 V B=Calc(rs[p],ls[p],m/2,k-m/2,0,0); for(auto i:A) ans=(ans+1ll*D2(i.first)*i.second)%P; for(auto i:B) ans=(ans+1ll*D2(i.first)*i.second)%P; return; } Solve(ls[p],L/2),Solve(rs[p],L/2); } int main(){ n=rd(),k=rd(); rep(i,1,n) { int l=rd(),r=rd(); Ins(rt,0,U-1,l,r); } m=Up(k),Solve(rt,U); // O(1)求得完全覆盖部分的答案 int t=(2ll*D3(m/2)+1ll*D2(k-m/2+1)*m)%P; ans=(ans+1ll*cm*t)%P; printf("%d\n",ans); }
Texto alterado
Abrir arquivo
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair <int,int> Pii; #define mp make_pair #define pb push_back #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i) char IO; int rd(){ int s=0; while(!isdigit(IO=getchar())); do s=(s<<1)+(s<<3)+(IO^'0'); while(isdigit(IO=getchar())); return s; } const int N=2e4+10,P=1e9+7,I2=(P+1)/2,I3=(P+1)/3,U=1<<30; int n,m,k; int L[N],R[N]; int Check(){ for(int i=k;i;i>>=1) if(~i&1) return 0; return 1; } int D3(int n){ return 1ll*n*(n-1)/2%P*(n-2)%P*I3%P; } int D2(int n){ return 1ll*n*(n-1)/2%P; } const int M=N*60; int s[M],ls[M],rs[M],t[M],cnt,rt; //在线段树上插入节点,打上标记,同时处理出size便于下面计算 void Ins(int &p,int l,int r,int ql,int qr){ if(!p) p=++cnt; s[p]+=min(qr,r)-max(ql,l)+1; if(ql<=l && r<=qr) { t[p]=1; return; } int mid=(l+r)>>1; if(ql<=mid) Ins(ls[p],l,mid,ql,qr); if(qr>mid) Ins(rs[p],mid+1,r,ql,qr); } int ans; // O(1)求出m int Up(int k){ return 1<<(32-__builtin_clz(k)); } typedef vector <Pii> V; V Union(const V &A,const V &B){ int p1=0,p2=0,s1=A.size(),s2=B.size(); V R; // 这里是否归并并不影响复杂度 while(p1<s1 || p2<s2) { if(p1<s1 && (p2==s2||A[p1]<B[p2])) { if(R.size() && R.back().first==A[p1].first) R.back().second+=A[p1].second; else R.pb(A[p1]); p1++; } else { if(R.size() && R.back().first==B[p2].first) R.back().second+=B[p2].second; else R.pb(B[p2]); p2++; } } return R; } V Calc(int a,int b,int L,int k,int f1,int f2){ f1|=t[a],f2|=t[b]; V Res; // 底层情况O(1)解决 if(!f1 && !a) return Res; if(f2) return Res.pb(mp(k+1,f1?L:s[a])),Res; if(!b) return Res.pb(mp(0,f1?L:s[a])),Res; int m=Up(k); // L>m说明还要继续进行分裂 if(L>m) return Union(Calc(ls[a],ls[b],L/2,k,f1,f2),Calc(rs[a],rs[b],L/2,k,f1,f2)); // 进入降阶子问题,左查右,右查左 k-=m/2; V A=Calc(ls[a],rs[b],L/2,k,f1,f2); for(auto &i:A) i.first+=f2?L/2:s[ls[b]]; V B=Calc(rs[a],ls[b],L/2,k,f1,f2); for(auto &i:B) i.first+=f2?L/2:s[rs[b]]; return Union(A,B); } int cm; // 第一次分裂 void Solve(int p,int L){ if(!p) return; // 完全覆盖的部分答案可以快速求出 if(t[p]) { cm+=L/m; return; } // 已经完成分裂,此时进入第一层子问题 if(L==m) { // 贡献分为 // 左选3 , 右选 3 ans=(ans+D3(s[ls[p]]))%P,ans=(ans+D3(s[rs[p]]))%P; // 左1,右2 V A=Calc(ls[p],rs[p],m/2,k-m/2,0,0); // 左2,右1 V B=Calc(rs[p],ls[p],m/2,k-m/2,0,0); for(auto i:A) ans=(ans+1ll*D2(i.first)*i.second)%P; for(auto i:B) ans=(ans+1ll*D2(i.first)*i.second)%P; return; } Solve(ls[p],L/2),Solve(rs[p],L/2); } int main(){ n=rd(),k=rd(); rep(i,1,n) { int l=rd(),r=rd(); Ins(rt,0,U-1,l,r); } m=Up(k),Solve(rt,U); // O(1)求得完全覆盖部分的答案 int t=(2ll*D3(m/2)+1ll*D2(k-m/2+1)*m)%P; ans=(ans+1ll*cm*t)%P; printf("%d\n",ans); }
Encontrar Diferença