标签:splay 差分 opened 数位 oid view freopen res ret
https://file.floj.tech/export/kCYc2UPJUy078iiYl7Z9
t1
如果长度为偶数则必定满足条件三,所以答案为2^{n/2}。
如果是奇数先分成两半,中间的数为0,2,4,6,8,就是求奇数位偶数位的差分别为这些数有好多种情况,使用容斥计算。
就是计算如果任意个数超过9-至少有一个超过9+至少两个超过九……。
代码如下:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
const int mo=1e9+7;
const int dao=3e6+5;
int t,inv[dao],jc[dao],n;
inline int read()
{
char c=getchar();
int x=0,f=1;
while(!isdigit(c)) {if(c==‘-‘) f=-1;c=getchar();}
while(isdigit(c)) {x=(x<<3)+(x<<1)+c-‘0‘;c=getchar();}
return x*f;
}
inline int hapow(int x,int y)
{
int daan=1;
while(y)
{
if(y&1) daan=(1ll*daan*x)%mo;
x=(1ll*x*x)%mo;
y>>=1;
}
return daan;
}
inline void init()
{
jc[0]=jc[1]=inv[0]=inv[1]=1;
for(int i=2; i<dao;++i) jc[i]=1ll*jc[i-1]*i%mo, inv[i]=mo-(int)inv[mo%i]*(mo/i)%mo;
for(int i=1; i<dao;++i) inv[i]=(int)inv[i-1]*inv[i]%mo;
}
inline int C(int x,int y)
{
return jc[x]*inv[y]%mo*inv[x-y]%mo;
}
inline int clac(int du)
{
int ans=0;
for(int i=0;i<=n&&du>=i*10;i++) ans+=(((i&1)?-1ll:1ll)*C(n,i)%mo*C(n+du-1-i*10,n-1))%mo,ans+=mo,ans%=mo;
return ans;
}
signed main()
{
init();
t=read();
while(t--)
{
n=read();
if(!(n&1))
{
cout<<hapow(10,n/2)<<"\n";
continue;
}
else
{
int ans=0;
n>>=1;
int dao=9*(n-n/2);
for(int i=-4;i<=0;i++) ans=(ans+clac(i+dao))%mo,ans+=mo,ans%=mo;
cout<<ans<<"\n";
}
}
}
t2
发现将奇数位偶数位分开处理即可。直接贪心,如果左边的个数多了,则必须放到右边去,先从左往右扫如果可以放就将当前最小的放在当前位置,再从右往左扫回来,将当前最大的放在当前位置即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],ji[N][2],ou[N][2],sizj,sizo,hu1[N],hu2[N],hu3[N],hu4[N];
inline int read()
{
char c=getchar();
int x=0,f=1;
while(!isdigit(c)) {if(c==‘-‘) f=-1;c=getchar();}
while(isdigit(c)) {x=(x<<3)+(x<<1)+c-‘0‘;c=getchar();}
return x*f;
}
priority_queue <int> que;
inline int work(int * f,int pu)
{
int you=0,res=0;
for(int i=1;i<=n;i++)
{
if(f[i])
{
you++;
if(you>0) que.push(-f[i]),f[i]=0;
}
if(i%2==pu)
{
if(you>=1) f[i]=-que.top(),que.pop();
you--;
}
int hu=que.size();
res+=hu;
}
while(!que.empty()) que.pop();you=0;
for(int i=n;i>=1;i--)
{
if(f[i])
{
you++;
if(you>0) que.push(f[i]),f[i]=0;
}
if(i%2==pu)
{
if(you>=1) f[i]=que.top(),que.pop();
you--;
}
int hu=que.size();
res+=hu;
}
return res;
}
int pan;
inline bool guishiyidaozhan()
{
for(int i=1;i<=n;i++)
{
if((hu3[i]|hu4[i])<(hu1[i]|hu2[i]))
return 1;
if((hu3[i]|hu4[i])!=(hu1[i]|hu2[i]))
return 0;
}
return 0;
}
int main()
{
// freopen("sequence.in","r",stdin);
// freopen("sequence.out","w",stdout);
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++)
{
if(a[i]%2==1)
ji[++sizj][0]=a[i],ji[sizj][1]=i;
else ou[++sizo][0]=a[i],ou[sizo][1]=i;
}
for(int i=1;i<=sizj;i++) hu1[ji[i][1]]=hu3[ji[i][1]]=ji[i][0];
for(int i=1;i<=sizo;i++) hu2[ou[i][1]]=hu4[ou[i][1]]=ou[i][0];
if(n&1)
{
if(sizj>sizo) work(hu1,1),work(hu2,0);
else work(hu2,1),work(hu1,0);
}
else
{
int gu1=work(hu1,1)+work(hu2,0);
int gu2=work(hu3,0)+work(hu4,1);
if(gu1>gu2||(gu1==gu2&&guishiyidaozhan())) pan=1;
}
if(pan==0) for(int i=1;i<=n;i++) if(hu1[i]) cout<<hu1[i]<<" "; else cout<<hu2[i]<<" ";
else for(int i=1;i<=n;i++) if(hu3[i]) cout<<hu3[i]<<" "; else cout<<hu4[i]<<" ";
fclose(stdin);fclose(stdout);
return 0;
}
标签:splay 差分 opened 数位 oid view freopen res ret
原文地址:https://www.cnblogs.com/betablewaloot/p/12305434.html