Description:
定义一个数为 happy h a p p y ,即只有一位上的数与其它位上的数不同,询问 [a,b] [ a , b ] 内 happy h a p p y 数的个数.
a≤b≤1016 a ≤ b ≤ 10 16
Solution:
Code:
#include
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;++i)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;--i)
#define db double
#define ll long long
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define MINF 0xc0c0c0c0
#define Sz(A) sizeof(A)
#define mcl(A,b) memset(A,b,Sz(A))
#define mcp(A,b) memcpy(A,b,Sz(b))
#define pb push_back
#define fi first
#define se second
templateinline bool chkmin(T &x,T y){return y1 :0;}
templateinline bool chkmax(T &x,T y){return x1:0;}
typedef pair<int,int>PII;
#define N 18
ll a,b;
struct p100{
int get(ll x){
int cnt=0;
while(x){
cnt++;
x/=10;
}
return cnt;
}
ll change(int len,int pos,int x,int y){
ll num=0;
if(!x && pos>1 || !y && pos==1)return 0;
SREP(i,1,pos)num=num*10+x;
num=num*10+y;
REP(i,pos+1,len)num=num*10+x;
return num;
}
ll calc(int top){
ll res=0;
SREP(i,0,10) SREP(j,0,10) if(i!=j){
REP(k,1,top){
ll tmp=change(top,k,i,j);
if(a<=tmp && tmp<=b)res++;
}
}
return res;
}
void solve(){
int len1=get(a);
int len2=get(b);
// printf("len1=%d len2=%d\n",len1,len2);
ll ans=0;
REP(i,len1,len2){
if(i<2)continue;
if(i==2)SREP(j,10,100)ans+=(j>=a && j<=b);
else ans+=calc(i);
}
printf("%lld\n",ans);
}
}p2;
int main(){
// freopen("happy.in","r",stdin);
// freopen("happy.out","w",stdout);
scanf("%lld%lld",&a,&b);
p2.solve();
return 0;
}
Description:
在 [1,n] [ 1 , n ] 球中染色,使任意 [i,i+m−1] [ i , i + m − 1 ] 内都至少有 2 2 个球被染色,染色代价为 c[i] c [ i ] .
n≤20000,m≤2000,ci≤20000 n ≤ 20000 , m ≤ 2000 , c i ≤ 20000
Solution:
Code:
#include
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;++i)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;--i)
#define db double
#define ll long long
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define MINF 0xc0c0c0c0
#define Sz(A) sizeof(A)
#define mcl(A,b) memset(A,b,Sz(A))
#define mcp(A,b) memcpy(A,b,Sz(b))
#define pb push_back
#define fi first
#define se second
templateinline bool chkmin(T &x,T y){return y1 :0;}
templateinline bool chkmax(T &x,T y){return x1:0;}
typedef pair<int,int>PII;
#define N 20002
#define M 2001
int n,m;
int c[N];
struct p30{
bool mark[22];
bool check(){
REP(i,1,n-m+1){
int cnt=0;
REP(j,i,i+m-1)cnt+=mark[j];
if(cnt<2)return 0;
}
return 1;
}
void solve(){
int ans=INF;
SREP(s,0,1<0);
SREP(i,0,n) if(s&(1<1]=1;
if(check()){
int sum=0;
REP(i,1,n) if(mark[i]) sum+=c[i];
chkmin(ans,sum);
}
}
printf("%d\n",ans);
}
}p1;
struct p100{
int dp[M+5][M+5];
void solve(){
mcl(dp,INF);
REP(i,1,m) SREP(j,1,i) dp[i][j]=c[i]+c[j];
SREP(j,2,n){
int mn=INF;
for(int i=j+m-1;i>j && i>m;--i){
chkmin(mn,dp[j%M][(i-m)%M]);
dp[i%M][j%M]=mn+c[i];
}
}
int ans=INF;
REP(i,n-m+1,n) for(int j=i-1;i-j"%d\n",ans);
}
}p2;
struct p60{
int dp[502][502];
void solve(){
mcl(dp,INF);
REP(i,1,m)dp[i][0]=c[i];
REP(i,1,n+1) SREP(j,max(0,i-m+1),i) SREP(k,max(0,i-m),j) chkmin(dp[i][j],dp[j][k]+c[i]);
int ans=INF;
REP(i,0,n) chkmin(ans,dp[n+1][i]);
printf("%d\n",ans);
}
}p3;
int main(){
// freopen("paint.in","r",stdin);
// freopen("paint.out","w",stdout);
scanf("%d%d",&n,&m);
REP(i,1,n) scanf("%d",&c[i]);
if(n<=20)p1.solve();
else if(n<=500 && m<=100)p3.solve();
else p2.solve();
return 0;
}
Description:
求一棵树上条不相交的路径的长度的乘积的最大值.
n≤105 n ≤ 10 5
Solution:
Code:
#include
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;++i)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;--i)
#define db double
#define ll long long
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define MINF 0xc0c0c0c0
#define Sz(A) sizeof(A)
#define mcl(A,b) memset(A,b,Sz(A))
#define mcp(A,b) memcpy(A,b,Sz(b))
#define pb push_back
#define fi first
#define se second
template<class T>inline bool chkmin(T &x,T y){return y1 :0;}
template<class T>inline bool chkmax(T &x,T y){return x1:0;}
typedef pair<int,int>PII;
#define N 100002
int n;
vector<int>E[N];
struct p20{
int sz[N],son[N],fa[N],dep[N],top[N];
void dfs1(int x,int f){
sz[x]=1;
son[x]=0;
fa[x]=f;
dep[x]=dep[f]+1;
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==f)continue;
dfs1(y,x);
sz[x]+=sz[y];
if(sz[son[x]]void dfs2(int x,int tp){
top[x]=tp;
if(son[x])dfs2(son[x],tp);
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==fa[x] || y==son[x])continue;
dfs2(y,y);
}
}
int Lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]return dep[x]bool mark[22];
void push(int x,int y,int lca){
mcl(mark,0);
while(x!=lca){
mark[x]=1;
x=fa[x];
}
while(y!=lca){
mark[y]=1;
y=fa[y];
}
mark[lca]=1;
}
bool check(int x,int y,int lca){
if(mark[lca])return 0;
while(x!=lca){
if(mark[x])return 0;
x=fa[x];
}
while(y!=lca){
if(mark[y])return 0;
y=fa[y];
}
return 1;
}
void solve(){
dfs1(1,0);
dfs2(1,1);
ll ans=0;
REP(x1,1,n) REP(y1,x1+1,n) REP(x2,1,n) REP(y2,x2+1,n) {
int lca1=Lca(x1,y1),lca2=Lca(x2,y2);
push(x1,y1,lca1);
if(check(x2,y2,lca2)){
int d1=dep[x1]+dep[y1]-2*dep[lca1];
int d2=dep[x2]+dep[y2]-2*dep[lca2];
chkmax(ans,1ll*d1*d2);
}
}
printf("%lld\n",ans);
}
}p1;
struct p2{
ll dp[N][5];
ll ans;
void update(int x,int op,int &m1,int &m2){
ll t=dp[x][op]+1;
if(t>m1)m2=m1,m1=t;
else if(t>m2)m2=t;
}
void dfs1(int x,int f){
int mx1=0,mx2=0,len1=0,len2=0;
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==f)continue;
dfs1(y,x);
chkmax(dp[x][1],dp[y][1]+1);
chkmax(dp[x][3],dp[y][3]);
chkmax(dp[x][2],dp[y][2]);
update(y,1,mx1,mx2);
update(y,2,len1,len2);
}
chkmax(dp[x][2],1ll*(mx1+mx2));
chkmax(dp[x][3],1ll*len1*len2);
}
void dfs2(int x,int f,int ye,int tmp){
int mx1=0,mx2=0,t=0;
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==f)continue;
if(dp[y][1]+1>mx1)mx2=mx1,mx1=dp[y][1]+1,t=y;
else if(dp[y][1]+1>mx2)mx2=dp[y][1]+1;
}
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==f)continue;
int num=max(tmp,ye+(int)(y==t?mx2:mx1));
chkmax(ans,dp[y][2]*num);
dfs2(y,x,max((int)(y==t?mx2:mx1),ye)+1,num);
}
}
void solve(){
dfs1(1,0);
ans=dp[1][3];
dfs2(1,0,0,0);
printf("%lld\n",ans);
}
}p2;
PII em[N];
struct p80{
int id1,id2;
int len1,len2;
void dfs1(int x,int f,int sum){
if(chkmax(len1,sum))id1=x;
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==f || mp[x][y])continue;
dfs1(y,x,sum+1);
}
}
void dfs2(int x,int f,int sum){
chkmax(len1,sum);
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==f || mp[x][y])continue;
dfs2(y,x,sum+1);
}
}
void dfs3(int x,int f,int sum){
if(chkmax(len2,sum))id2=x;
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==f || mp[x][y])continue;
dfs3(y,x,sum+1);
}
}
void dfs4(int x,int f,int sum){
chkmax(len2,sum);
SREP(i,0,E[x].size()){
int y=E[x][i];
if(y==f || mp[x][y])continue;
dfs4(y,x,sum+1);
}
}
map<int,bool>mp[N];
void solve(){
ll ans=0;
SREP(i,1,n){
int a=em[i].fi,b=em[i].se;
mp[a][b]=mp[b][a]=1;
len1=len2=0;
id1=a,id2=b;
dfs1(a,0,0);
dfs2(id1,0,0);
dfs3(b,0,0);
dfs4(id2,0,0);
chkmax(ans,1ll*len1*len2);
mp[a][b]=mp[b][a]=0;
}
printf("%lld\n",ans);
}
}p3;
int main(){
// freopen("repair.in","r",stdin);
// freopen("repair.out","w",stdout);
scanf("%d",&n);
SREP(i,1,n){
int a,b;
scanf("%d%d",&a,&b);
em[i]=(PII){a,b};
E[a].pb(b);
E[b].pb(a);
}
if(n<=20)p1.solve();
else if(n<=1000)p3.solve();
else p2.solve();
return 0;
}
Summary: