天天看點

楊輝三角fac的C語言代碼,牛客挑戰賽39(A(枚舉+遞增+二分),B(二分+hash),C(線段樹-等差數組),E(楊輝三角組合數))...

題目連結

A-聚會

題意:

楊輝三角fac的C語言代碼,牛客挑戰賽39(A(枚舉+遞增+二分),B(二分+hash),C(線段樹-等差數組),E(楊輝三角組合數))...

做法:看了别人的代碼我覺得我的做法太複雜了。

稍微分析下一個可做的做法:兩個傳送,一定一個在0處,否則相當于沒用

正數負數分開考慮,對于正數數組,排序後   一定是某個i與最後一個的中間位置放置一個傳送,那我們就枚舉中間的位置,然後計算目前最大距離。

且一定是這個傳送門的左邊的某些點  能往右走最近,那我用遞增的方法,找到小于傳送目前坐标t的第一個數:now,接着從now通過二分  找到最遠   且往右邊走小于左邊走第一個點 這樣就找到我想要的點了,維護一下即可

#include#define rep(i,a,b) for(int i=a;i<=(b);++i)

#define per(i,a,b) for(int i=a;i>=(b);--i)

#define mem(a,x) memset(a,x,sizeof(a))

#define pb push_back

#define pi pair#define mk make_pair

using namespace std;

typedef long long ll;

ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

const int N=1e5+10;

ll n,a[N],x[N],y[N],l1,l2;

ll f[40],ans;

void run(ll x[],ll y[],ll len1,ll len2)

{

rep(i,1,len1)

{

ll t=(x[i]+x[len1])/2;

ll mx=max(y[len2],x[len1]-t);

int now=1;

for(int k=27;k>=0;--k){

if(now+f[k]>len1) continue;

if(x[now+f[k]]>=t) continue;

now=now+f[k];

}

int l=1,r=now;

while(l<=r)

{

int mid=l+r>>1;

if(x[mid]>t-x[mid]) r=mid-1,now=mid;

else l=mid+1;

}

mx=max(mx,min(x[now],t-x[now]));

if(now-1>0) mx=max(mx,min(x[now-1],t-x[now-1]));

//printf("now:%d mx:%lld t:%lld\n",now,mx,t);

ans=min(ans,mx);

}

}

void solve()

{

cin>>n;

ans=l1=l2=0;

rep(i,1,n)

{

scanf("%lld",&a[i]);ans=max(ans,abs(a[i]));

if(a[i]<0) x[++l1]=-a[i];else if(a[i]>0) y[++l2]=a[i];

}

sort(x+1,x+1+l1);

sort(y+1,y+1+l2);

run(x,y,l1,l2);

run(y,x,l2,l1);

printf("%lld\n",ans);

}

int main()

{

f[0]=1;

for(int i=1;i<=28;++i) f[i]=f[i-1]*2;

int _;cin>>_;while(_--)

solve();

}

B-密碼系統

楊輝三角fac的C語言代碼,牛客挑戰賽39(A(枚舉+遞增+二分),B(二分+hash),C(線段樹-等差數組),E(楊輝三角組合數))...

做法:枚舉每輪k  以及各個下标(j+=k的枚舉)

然後通過二分  判斷目前位置j  和目前最小位置i   找到相同的字首len  通過判斷j+len 與i+len 的字元 來維護答案。

官方做法好像是字尾數組,不太會。。

#includeusing namespace std;

const int N = 1e6 + 10;

//base[i]進制

typedef long long ll;

ll h[3][N];

ll base[3]={43,47,41};

ll mod[3] = {1000000007,998244353,1000000009};

ll f[3][N];

int n,k,ans[N];

int getid(char c) {

return c-'a';

}

char s[N];

void init()

{

f[1][0]=f[0][0]=1;

for(int i=1;i>1;

ll t1, t2;

t1=getvalue(x,x+mid-1,0);

t2=getvalue(y,y+mid-1,0);

//for(int j=0;j<=1;++j)

if(t1==t2) l=mid+1,ans=mid;

else r=mid-1;

}

return ans;

}

int main()

{

init();

cin>>n>>k;

cin>>s+1;

for(int i=1;i<=n;++i) s[n+i]=s[i];

n=2*n;

for(int i=1;i<=n;++i){

for(int j=0;j<=1;++j) h[j][i]=(h[j][i-1]*base[j]%mod[j]+getid(s[i]))%mod[j];

}

//puts("***");

for(int i=1;i<=k;++i){

ans[i]=i;

for(int j=i+k;j<=n;j+=k){

int len=get(ans[i],j);

//printf("i:%d j:%d len:%d\n",i,j,len);

if(len==k) continue;

if(s[ans[i]+len]s[ans[i]+len]) id=ans[i];

}

for(int i=0;i

C-牛牛的等差數列

楊輝三角fac的C語言代碼,牛客挑戰賽39(A(枚舉+遞增+二分),B(二分+hash),C(線段樹-等差數組),E(楊輝三角組合數))...

線段樹 的模闆題了

#include#define rep(i,a,b) for(int i=a;i<=(b);++i)

#define per(i,a,b) for(int i=a;i>=(b);--i)

#define mem(a,x) memset(a,x,sizeof(a))

#define pb push_back

#define pi pair#define mk make_pair

using namespace std;

typedef long long ll;

ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

const int N=2e5+10;

const ll mod=111546435;

ll sum[4*N],lazy[4*N],D[4*N],pre[N];

int mp[50];

ll input(){

ll x=0,f=0;char ch=getchar();

while(ch'9') f|=ch=='-',ch=getchar();

while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();

return f? -x:x;

}

ll a[N];

int n;

void add(ll &x,ll y)

{

x=(x+y)%mod;

}

ll gets(ll a1,ll n,ll d)

{

return (n*a1%mod+n*(n-1)/2%mod*d%mod)%mod;

}

ll getv(ll a1,ll n,ll d)

{

return (a1+n*d%mod)%mod;

}

void pushdown(int id,int l,int r)

{

if(lazy[id]){

int mid=l+r>>1;

ll len1=mid-l+1,len2=r-mid;

add(lazy[id<<1],lazy[id]);

add(D[id<<1],D[id]);

ll newval=lazy[id]+len1*D[id]%mod;

newval%=mod;

add(lazy[id<<1|1],newval);

add(D[id<<1|1],D[id]);

add(sum[id<<1],gets(lazy[id],len1,D[id]));

add(sum[id<<1|1],gets(newval,len2,D[id]));

lazy[id]=D[id]=0;

}

}

void up(int id,int l,int r,int ql,int qr,ll val,ll d)

{

if(ql<=l&&r<=qr){

ll t=getv(val,l,d);

add(lazy[id],t);

add(D[id],d);

add(sum[id],gets(t,r-l+1,d));

return ;

}

pushdown(id,l,r);

int mid=l+r>>1;

if(ql<=mid) up(id<<1,l,mid,ql,qr,val,d);

if(qr>mid) up(id<<1|1,mid+1,r,ql,qr,val,d);

sum[id]=(sum[id<<1]+sum[id<<1|1])%mod;

}

ll qu(int id,int l,int r,int ql,int qr)

{

if(ql<=l&&r<=qr) return sum[id];

pushdown(id,l,r);int mid=l+r>>1;

ll res=0;

if(ql<=mid) res=qu(id<<1,l,mid,ql,qr);

if(qr>mid) add(res,qu(id<<1|1,mid+1,r,ql,qr));

return res;

}

int main()

{

pre[0]=0;

n=input();rep(i,1,n) {a[i]=input();pre[i]=(pre[i-1]+a[i])%mod;}

int q;q=input();while(q--){

int op;op=input();

ll l,r,val,d;

l=input();r=input();val=input();

if(l>r) swap(l,r);

if(op==1){

d=input();up(1,1,n,l,r,(val-l*d%mod+mod)%mod,d);

}

else {

ll ans=(qu(1,1,n,l,r)+pre[r]-pre[l-1]+mod)%mod;

printf("%lld\n",ans%val);

}

}

}

E-牛牛與序列

楊輝三角fac的C語言代碼,牛客挑戰賽39(A(枚舉+遞增+二分),B(二分+hash),C(線段樹-等差數組),E(楊輝三角組合數))...

官方題解:

楊輝三角fac的C語言代碼,牛客挑戰賽39(A(枚舉+遞增+二分),B(二分+hash),C(線段樹-等差數組),E(楊輝三角組合數))...

打表程式:

#includeusing namespace std;

const int N=1e3+10;

typedef long long ll;

ll dp[N][N];

int n,k;

int main()

{

n=10,k=10;

for(int i=1;i<=k;++i) dp[1][i]=1;

for(int i=2;i<=n;++i){

for(int now=1;now<=k;++now)

for(int j=1;j<=now;++j){

dp[i][now]+=dp[i-1][j];

}

}

for(int i=1;i<=n;++i){

for(int j=1;j<=n;++j){

printf("%lld ",dp[i][j]);

}

puts("");

}

}

打表結果:

楊輝三角fac的C語言代碼,牛客挑戰賽39(A(枚舉+遞增+二分),B(二分+hash),C(線段樹-等差數組),E(楊輝三角組合數))...

典型的楊輝三角了。。

至于求組合數不能用lucas(我逾時)原因是lucas的複雜度是log(n)*p   p是模數,這裡模數比較大,k比較小,考慮約分一下即可

#include#define rep(i,a,b) for(int i=a;i<=(b);++i)

#define mem(a,x) memset(a,x,sizeof(a))

#define pb push_back

#define pi pair#define mk make_pair

using namespace std;

typedef long long ll;

ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

const ll p=998244353;

const ll mod=998244353;

const int N=1e6+10;

ll fac[N],inv[N],ifac[N];

ll C(int n,int m)

{

ll ans=1;

rep(i,1,m) ans=ans*(n-i+1)%mod;

return ans*ifac[m]%mod;

}

ll powmod(ll a,ll b,ll mod)

{

ll res=1;

for(;b;b>>=1){

if(b&1) res=res*a%mod;

a=a*a%mod;

}

return res;

}

void init()

{

fac[0]=inv[1]=ifac[0]=1;

rep(i,1,N-1) fac[i]=fac[i-1]*i%mod;

rep(i,2,N-1) inv[i]=inv[mod%i]*(mod-mod/i)%mod;

rep(i,1,N-1) ifac[i]=ifac[i-1]*inv[i]%mod;

}

int main()

{

init();

int _;cin>>_;while(_--)

{

ll n,k;

scanf("%lld%lld",&n,&k);

ll mi=min(k-1,n);

ll ans=((powmod(k,n,p)-2ll*C(n+k-1,mi)+p+p)%p+k)%p;

printf("%lld\n",ans);

}

}

繼續閱讀