1. 程式人生 > >【pG&&CYH-01】元旦聯歡會

【pG&&CYH-01】元旦聯歡會

題解:

t1:

題解是迴圈矩陣

但我並沒有往矩陣上想下去。。。

這個東西比較顯然的是可以把它看成生成函式

然後就可以任意模數fft了

複雜度比題解優 $nlog^2$

t2:

隨便推推式子就好了

t3:

矩陣的一般套路

維護$f(n-1),f(n-2),{f(n-1)}^2,{f(n-2)}^2,f(n-1)*f(n-2)$

他們之間是可以遞推的

t4:不會

t5:

這種題目比較顯然是找規律

然後會發現2^i-2^i+1的差是等差數列

暴力做是nlogn的

我們可以利用一些優化做到O(n)

對2^n的打表(當然我oeis了一下是有遞推式的)

然後快速查某個數有幾位(builtin 但noi賽事都不能用於是我就手動實現了)

然而這題空間開16m不知道意義何在

fread的快讀和快輸都不能用。。。

不用快讀快輸顯然過不了

還得從網上拉了個getchar的。。很煩。。

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define dep(i,t,h) for (int i=t;i>=h;i--)
#define ll long long
namespace
IO{ /* char ss[1<<24],*A=ss,*B=ss; IL char gc() { return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; } template<class T>void read(T &x) { rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48); while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; }
*/ char sr[1<<24],z[20];int C=-1,Z=0; template<class T>void wer(T x) { if (x<0) sr[++C]='-',x=-x; while (z[++Z]=x%10+48,x/=10); while (sr[++C]=z[Z],--Z); } IL void wer1() {sr[++C]=' ';} IL void wer2() {sr[++C]='\n';} }; using namespace IO; const int mo=1e9+7; int wa[100000]; ll p[70]={0,0ll, 2ll, 14ll, 70ll, 310ll, 1302ll, 5334ll, 21590ll, 86870ll, 348502ll, 1396054ll, 5588310ll, 22361430ll, 89462102ll, 357881174ll, 431590223ll, 726491955ll, 906229948ll, 625444057ll, 502824788ll, 13396288ll, 57779454ll, 239506422ll, 974802902ll, 932766017ll, 798172909ll, 326909341ll, 576072811ll, 841162140ll, 438390354ll, 901045041ll, 899147409ll, 186524142ll, 925965631ll, 63600624ll, 973878754ll, 334467499ll, 215775006ll, 618910060ll, 987260307ll, 972281364ll, 935605751ll, 835383617ll, 527455717ll, 481665396ll, 670346656ll, 168756770ll, 649767409ll, 548550282ll, 93162436ll, 170572390ll, 278134854ll, 304230006ll, 600301213ll, 167967225ll, 205393676ll, 888624265ll, 688596163ll, 22582881ll, 626728026ll}; IL int getws(ll x) { if (x>>48) return 48+wa[x>>48]; if (x>>32) return 32+wa[x>>32]; if (x>>16) return 16+wa[x>>16]; return wa[x]; } IL ll js(ll x) { int k=getws(x); ll now=1ll<<(k-1); return (p[k-1]+((x-now)%mo)*((x-now+1)%mo)%mo)%mo; } ll read(){ ll w=1,q=0;char ch=' '; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')q=q*10+ch-'0',ch=getchar(); return w*q; } void write(ll x) { if(x<0){putchar('-');x=~(x-1);} int s[20],top=0; while(x){s[++top]=x%10;x/=10;} if(!top)s[++top]=0; while(top)putchar(s[top--]+'0'); } int main() { freopen("1.in","r",stdin); freopen("2.out","w",stdout); rep(i,1,65538) wa[i]=wa[i>>1]+1; int n; ios::sync_with_stdio(false); n=read(); rep(i,1,n) { ll k; k=read(); write(js(k)); printf("\n"); } return 0; }
View Code

 t6:

資料範圍寫成這樣出題人真的是nb

首先每個點都可以用組合數表示出來

然後再推推式子就得到全部的了