@Pinetrie
2019-08-25T06:48:19.000000Z
字数 17882
阅读 984
l到r的数字中没有4和62的数有多少个
#include <bits/stdc++.h>using namespace std;int n,m,dp[20][2],num[20];int dfs(int pos,int if6,int limit){if(pos == 0) return 1;if(!limit && dp[pos][if6] != -1) return dp[pos][if6];int up = limit ? num[pos] : 9;int temp = 0;for(int i = 0;i <= up;i++){if(i == 4) continue;if(if6 == 1 && i == 2) continue;temp += dfs(pos - 1,i == 6,limit && i == num[pos]);}if(!limit) dp[pos][if6] = temp;return temp;}int solve(int x){int tot = 0;while(x){num[++tot] = x % 10;x /= 10;}return dfs(tot,0,1);}int main(){while(scanf("%d %d",&n,&m) && (n + m)){memset(dp,-1,sizeof(dp));printf("%d\n",solve(m) - solve(n - 1));}return 0;}
求最小顶点覆盖集的方法:
如果是拿匈牙利跑的话,需要求出最大匹配后,从左部的每个非匹配点再跑dfs,最终左边未被标记的点,与右边被标记的点就是覆盖的点集。如果是拿dinic分层跑的话,左部的点就是d[]为0的点,右部就是d[]不为0的点。
#include <bits/stdc++.h>#define MAX_V 1100using namespace std;int V,P;vector<int> G[MAX_V];int match[MAX_V];bool used[MAX_V];void add_edge(int u,int v){G[u].push_back(v);G[v].push_back(u);}bool dfs(int v){used[v] = true;for(int i = 0;i < (int)G[v].size();i++){int u = G[v][i];if(!used[u]){used[u] = 1;if(match[u] == -1 || dfs(match[u])){match[u] = v;match[v] = u;return 1;}}}return false;}int binary_match(){int res = 0;memset(match,-1,sizeof(match));for(int v = 0; v < V; v++){if(match[v] < 0){memset(used,0,sizeof(used));if(dfs(v)){res++;}}}return res;}int main(){int T;scanf("%d",&T);while(T--){for(int i = 1;i <= MAX_V;i++) G[i].clear();scanf("%d %d",&P,&V);V += P;for(int i = 1;i <= P;i++){int n;scanf("%d",&n);for(int j = 1;j <= n;j++){int x;scanf("%d",&x);add_edge(i,x + P);}}int edge_num = binary_match();if(edge_num == P) printf("YES\n");else printf("NO\n");}return 0;}
#include <bits/stdc++.h>using namespace std;const double EPS = 1E-8;typedef vector<double> vec;typedef vector<vec> mat;//求解Ax = b,其中A是方阵////当方程无解或无穷多解时,返回一个长度为0的数组//vec gauss_jordan(const mat& A,const vec& b){int n = A.size();mat B(n,vec(n + 1));for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)B[i][j] = A[i][j];//把b存放在A的右边方便一起处理//for(int i = 0; i < n; i++)B[i][n] = b[i];for(int i = 0; i < n; i++){//把正在处理的未知数系数最大的式子换到第i行//int pivot = i;for(int j = i; j < n; j++){if(abs(B[j][i] > abs(B[pivot][i])))pivot = j;}swap(B[i],B[pivot]);//无解或者无穷多解//if(abs(B[i][i]) < EPS)return vec();//把正在处理的未知数系数边为1//for(int j = i + 1; j <= n; j++)B[i][j] /= B[i][i];for(int j = 0; j < n; j++){if(i != j){//从第j个式子中消去第i个未知数//for(int k = i + 1; k <= n; k++)B[j][k] -= B[j][i] * B[i][k];}}}vec x(n);//存放在右边的b就是答案//for(int i = 0; i < n; i++)x[i] = B[i][n];return x;}int main(){int n;scanf("%d",&n);mat A(n,vec(n));vec B(n);for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){double val;scanf("%lf",&val);A[i][j] = val;}}for(int i = 0; i < n; i++){double val;scanf("%lf",&val);B[i] = val;}vec C = gauss_jordan(A,B);for(int i = 0; i < n; i++)printf("%f ",C[i]);return 0;}/*输入:31 -2 34 -5 67 -8 106 12 21输出:1.00000 2.00000 3.00000*/
#include <bits/stdc++.h>using namespace std;const int maxn = 40010;int n,m,tot,qtot;int head[maxn * 2],qhead[maxn * 2],dis[maxn],vis[maxn],fa[maxn],LCA[maxn];struct NODE{int v,next,w;}node[maxn * 2];struct QNODE{int v,next,w;}qnode[maxn * 2];struct ASK{int x1,x2;}ask[maxn];void init(){memset(head,-1,sizeof(head));memset(qhead,-1,sizeof(qhead));memset(dis,0x3f3f3f3f,sizeof(dis));dis[1] = 0;memset(vis,0,sizeof(vis));for(int i = 1;i <= n;i++) fa[i] = i;tot = qtot = 0;}void addnode(int u,int v,int w){node[tot].v = v;node[tot].w = w;node[tot].next = head[u];head[u] = tot++;}void addnodeq(int u,int v,int w){qnode[qtot].v = v;qnode[qtot].w = w;qnode[qtot].next = qhead[u];qhead[u] = qtot++;}int Find(int x){if(x == fa[x]) return x;return fa[x] = Find(fa[x]);}void tarjan(int u){vis[u] = 1;for(int i = qhead[u];i != -1;i = qnode[i].next){int v = qnode[i].v;if(vis[v]) LCA[qnode[i].w] = Find(fa[v]);}for(int i = head[u];i != -1;i = node[i].next){int v = node[i].v,w = node[i].w;if(!vis[v]){dis[v] = dis[u] + w;tarjan(v);fa[v] = u;}}}int main(){int T;scanf("%d",&T);while(T--){scanf("%d %d",&n,&m);init();//for(int i = 1;i <= n;i++) printf("%d\n",fa[i]);//for(int i = 1;i < n;i++){int u,v,w;scanf("%d %d %d",&u,&v,&w);addnode(u,v,w);addnode(v,u,w);}for(int i = 1;i <= m;i++){int u,v;scanf("%d %d",&u,&v);addnodeq(u,v,i);addnodeq(v,u,i);ask[i].x1 = u,ask[i].x2 = v;}tarjan(1);for(int i = 1;i <= m;i++){int u = ask[i].x1,v = ask[i].x2;printf("%d\n",dis[u] + dis[v] - 2 * dis[LCA[i]]);}}return 0;}
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;#define maxn 2000#define base 10000struct Bign{int c[maxn],len,sign;//初始化Bign(){memset(c,0,sizeof(c)),len = 1,sign = 0;}//高位清零void Zero(){while(len > 1 && c[len] == 0)len--;if(len == 1 && c[len] == 0)sign = 0;}//压位读入void Write(char *s){int k = 1,l = strlen(s);for(int i = l - 1;i >= 0;i--){c[len] += (s[i] - '0') * k;k *= 10;if(k == base){k = 1;len++;}}}void Read(){char s[maxn] = {0};scanf("%s",s);Write(s);}//输出void Print(){if(sign)printf("-");printf("%d",c[len]);for(int i = len - 1;i >= 1;i--)printf("%04d",c[i]);printf("\n");}//重载 = 运算符,将低精赋值给高精Bign operator = (int a){char s[100];sprintf(s,"%d",a);Write(s);return *this;//this只能用于成员函数,表示当前对象的地址}//重载 < 运算符bool operator < (const Bign &a)const{if(len != a.len)return len < a.len;for(int i = len;i >= 1;i--){if(c[i] != a.c[i])return c[i] < a.c[i];}return 0;}bool operator > (const Bign &a)const{return a < *this;}bool operator <= (const Bign &a)const{return !(a < *this);}bool operator >= (const Bign &a)const{return !(*this < a);}bool operator != (const Bign &a)const{return a < *this || *this < a;}bool operator == (const Bign &a)const{return !(a < *this) && !(*this < a);}bool operator == (const int &a)const{Bign b;b = a;return *this == b;}//重载 + 运算符Bign operator + (const Bign &a){Bign r;r.len = max(len,a.len) + 1;for(int i = 1;i <= r.len;i++){r.c[i] += c[i] + a.c[i];r.c[i + 1] += r.c[i] / base;r.c[i] %= base;}r.Zero();return r;}Bign operator + (const int &a){Bign b;b = a;return *this + b;}//重载 - 运算符Bign operator - (const Bign &a){Bign b,c;// b - cb = *this;c = a;if(c > b){swap(b,c);b.sign = 1;}for(int i = 1;i <= b.len;i++){b.c[i] -= c.c[i];if(b.c[i] < 0){b.c[i] += base;b.c[i + 1]--;}}b.Zero();return b;}Bign operator - (const int &a){Bign b;b = a;return *this - b;}//重载 * 运算符Bign operator * (const Bign &a){Bign r;r.len = len + a.len + 2;for(int i = 1;i <= len;i++){for(int j = 1;j <= a.len;j++){r.c[i + j - 1] += c[i] * a.c[j];}}for(int i = 1;i <= r.len;i++){r.c[i + 1] += r.c[i] / base;r.c[i] %= base;}r.Zero();return r;}Bign operator * (const int &a){Bign b;b = a;return *this * b;}//重载 / 运算符Bign operator / (const Bign &b){Bign r,t,a;a = b;//if(a == 0)return r;r.len = len;for(int i = len;i >= 1;i--){t = t * base + c[i];int div,ll = 0,rr = base;while(ll <= rr){int mid = (ll + rr) / 2;Bign k = a * mid;if(k > t)rr = mid - 1;else{ll = mid + 1;div = mid;}}r.c[i] = div;t = t - a * div;}r.Zero();return r;}Bign operator / (const int &a){Bign b;b = a;return *this / b;}//重载 % 运算符Bign operator % (const Bign &a){return *this - *this / a * a;}Bign operator % (const int &a){Bign b;b = a;return *this % b;}};int main(){Bign a,b,c,d,e,f,g;a.Read();b.Read();c = a + b;c.Print();d = a - b;d.Print();e = a * b;e.Print();f = a / b;f.Print();g = a % b;g.Print();return 0;}
#include<iostream>using namespace std;int exgcd(int a,int b,int &x,int &y){if(b==0){x=1;y=0;return a;}int gcd=exgcd(b,a%b,x,y);int x2=x,y2=y;x=y2;y=x2-(a/b)*y2;return gcd;}int main(){int x,y,a,b;cout<<"请输入a和b:"<<endl;cin>>a>>b;cout<<"a和b的最大公约数:"<<endl;cout<<exgcd(a,b,x,y)<<endl;cout<<"ax+by=gcd(a,b) 的一组解是:"<<endl;cout<<x<<" "<<y<<endl;return 0;}
#include <bits/stdc++.h>using namespace std;const int maxn = 100010;char s[maxn],temp[2 * maxn];int p[2 * maxn];void init() {int n = strlen(s);temp[0] = '$';for(int i = 1;i <= n;i++) {temp[i * 2] = s[i - 1];temp[i * 2 - 1] = '#';}temp[n * 2 + 1] = '#';temp[n * 2 + 2] = '\0';}int manacher() {int n = 2 * strlen(s) + 1;int mx = 0,ans = 0,mark = 0;for(int i = 1;i <= n;i++) {if(mx > i) p[i] = min(mx - i,p[mark * 2 - i]);else p[i] = 1;while(temp[i + p[i]] == temp[i - p[i]]) p[i]++;if(i + p[i] > mx) {mx = p[i] + i;mark = i;}ans = max(ans,p[i]);}return ans - 1;}int main() {while(scanf("%s",s) != EOF) {init();printf("%d\n",manacher());}return 0;}
快速查询区间最值
#include <cstdio>#include <algorithm>using namespace std;const int maxn = 100010;int Min[maxn][20],Max[maxn][20],a[maxn];int n,q;struct RMQ{int log2[maxn];void init(){for(int i = 0;i <= n;i++) log2[i] = (i == 0 ? -1 : log2[i>>1] + 1);for(int j = 1;j < 20;j++){for(int i = 1;i + (1<<j) <= n + 1;i++){Min[i][j] = min(Min[i][j - 1],Min[i + (1<<(j - 1))][j - 1]);Max[i][j] = max(Max[i][j - 1],Max[i + (1<<(j - 1))][j - 1]);}}}int Min_query(int l,int r){int k = log2[r - l + 1];return min(Min[l][k],Min[r - (1<<k) + 1][k]);}int Max_query(int l,int r){int k = log2[r - l + 1];return max(Max[l][k],Max[r - (1<<k) + 1][k]);}};int main(){scanf("%d %d",&n,&q);for(int i = 1;i <= n;i++){scanf("%d",&a[i]);Min[i][0] = a[i];Max[i][0] = a[i];}RMQ rmq;rmq.init();for(int i = 1;i <= q;i++){int l,r;scanf("%d %d",&l,&r);printf("%d\n",rmq.Max_query(l,r) - rmq.Min_query(l,r));}return 0;}
离线解决区间询问
q*sqrt(n)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 500100;struct Que{ll l,r,id,block;Que() {}Que(ll l,ll r,ll id):l(l),r(r),id(id) {}bool operator < (const Que &rhs) const{if(block == rhs.block) return r < rhs.r;return block < rhs.block;}}ques[maxn];ll n,m,len;ll a[maxn];ll ansx[maxn],ansy[maxn],sum;ll cor[maxn];void add(ll x){sum += 2 * cor[x];cor[x]++;}void sub(ll x){sum -= (2 * cor[x] - 2);cor[x]--;}ll gcd(ll x,ll y){return y == 0 ? x : gcd(y,x % y);}int main(){scanf("%lld %lld",&n,&m);len = sqrt(n);for(int i = 1;i <= n;i++) scanf("%lld",&a[i]);for(int i = 1;i <= m;i++){ll l,r;scanf("%lld %lld",&l,&r);ques[i] = Que(l,r,i);ques[i].block = l / len;}sort(ques + 1,ques + 1 + m);ll L = 1,R = 1;cor[a[1]]++;sum = 0;for(int i = 1;i <= m;i++){ll l = ques[i].l,r = ques[i].r,id = ques[i].id;while(R < r) add(a[++R]);while(L > l) add(a[--L]);while(R > r) sub(a[R--]);while(L < l) sub(a[L++]);ll cnt1 = sum;ll cnt2 = (ll)(r - l + 1) * (r - l);if(cnt1 == 0){ansx[id] = 0,ansy[id] = 1;continue;}ll k = gcd(cnt1,cnt2);ansx[id] = cnt1 / k,ansy[id] = cnt2 / k;}for(int i = 1;i <= m;i++){printf("%lld/%lld\n",ansx[i],ansy[i]);}return 0;}
题目描述
如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作:
操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z
操作2: 格式: 2 x y 表示求树从x到y结点最短路径上所有节点的值之和
操作3: 格式: 3 x z 表示将以x为根节点的子树内所有节点值都加上z
操作4: 格式: 4 x 表示求以x为根节点的子树内所有节点值之和
输入格式:
第一行包含4个正整数N、M、R、P,分别表示树的结点个数、操作个数、根节点序号和取模数(即所有的输出结果均对此取模)。
接下来一行包含N个非负整数,分别依次表示各个节点上初始的数值。
接下来N-1行每行包含两个整数x、y,表示点x和点y之间连有一条边(保证无环且连通)
接下来M行每行包含若干个正整数,每行表示一个操作,格式如下:
操作1: 1 x y z
操作2: 2 x y
操作3: 3 x z
操作4: 4 x
输出格式:
输出包含若干行,分别依次表示每个操作2或操作4所得的结果(对P取模)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 100010;ll w[maxn],root;ll N,M,R,P;//线段树///////////////////////////////////////////////////////////////////ll A[maxn<<2],Sum[maxn<<2],Add[maxn<<2];void Pushup(ll rt){Sum[rt] = (Sum[rt<<1] + Sum[rt<<1|1]) % P;}void Pushdown(ll rt,ll ln,ll rn){if(Add[rt]){Add[rt<<1] = (Add[rt<<1] + Add[rt]) % P;Add[rt<<1|1] = (Add[rt<<1|1] + Add[rt]) % P;Sum[rt<<1] = (Sum[rt<<1] + ln * Add[rt]) % P;Sum[rt<<1|1] = (Sum[rt<<1|1] + rn * Add[rt]) % P;Add[rt] = 0;}}void build(ll l,ll r,ll rt){if(l == r){Sum[rt] = A[l];return;}ll m = (l + r)>>1;build(l,m,rt<<1);build(m + 1,r,rt<<1|1);Pushup(rt);}ll query(ll L,ll R,ll l,ll r,ll rt){if(L <= l && R >= r){return Sum[rt];}ll m = (l + r)>>1;Pushdown(rt,m - l + 1,r - m);ll Ans = 0;if(L <= m) Ans = (Ans + query(L,R,l,m,rt<<1)) % P;if(R > m) Ans = (Ans + query(L,R,m + 1,r,rt<<1|1)) % P;return Ans;}void update(ll L,ll R,ll C,ll l,ll r,ll rt){if(L <= l && R >= r){Sum[rt] = (Sum[rt] + (r - l + 1) * C) % P;Add[rt] = (Add[rt] + C) % P;return;}ll m = (l + r)>>1;Pushdown(rt,m - l + 1,r - m);if(L <= m) update(L,R,C,l,m,rt<<1);if(R > m) update(L,R,C,m + 1,r,rt<<1|1);Pushup(rt);}//////////////////////////////////////////////////////////预处理///////////////////////////////////////////////////ll head[maxn],f[maxn],dep[maxn],siz[maxn],son[maxn],rk[maxn],top[maxn],id[maxn];ll tot,cnt;struct Edge{ll v,next;}e[maxn * 2];void addnode(ll u,ll v){e[tot].v = v;e[tot].next = head[u];head[u] = tot++;}void dfs1(ll u,ll fa,ll deep){f[u] = fa;dep[u] = deep;siz[u] = 1;for(ll i = head[u];i != -1;i = e[i].next){ll v = e[i].v;if(v == fa) continue;dfs1(v,u,deep + 1);siz[u] += siz[v];if(siz[v] > siz[son[u]]) son[u] = v;}}void dfs2(ll u,ll t){top[u] = t;id[u] = ++cnt;rk[cnt] = u;if(!son[u]) return;dfs2(son[u],t);for(ll i = head[u];i != -1;i = e[i].next){ll v = e[i].v;if(v != son[u] && v != f[u]) dfs2(v,v);}}询问//////////////////////////////////////////ll getsum(ll x,ll y){ll ans = 0,fx = top[x],fy = top[y];while(fx != fy){if(dep[fx] >= dep[fy]){ans = (ans + query(id[fx],id[x],1,N,1)) % P;x = f[fx],fx = top[x];}else{ans = (ans + query(id[fy],id[y],1,N,1)) % P;y = f[fy],fy = top[y];}}if(id[x] <= id[y]) ans = (ans + query(id[x],id[y],1,N,1)) % P;else ans = (ans + query(id[y],id[x],1,N,1)) % P;return ans;}void getupdate(ll x,ll y,ll C){ll fx = top[x],fy = top[y];while(fx != fy){if(dep[fx] >= dep[fy]){update(id[fx],id[x],C,1,N,1);x = f[fx],fx = top[x];}else{update(id[fy],id[y],C,1,N,1);y = f[fy],fy = top[y];}}if(id[x] <= id[y]) update(id[x],id[y],C,1,N,1);else update(id[y],id[x],C,1,N,1);}ll getsonsum(ll x){return query(id[x],id[x] + siz[x] - 1,1,N,1);}void getsonupdate(ll x,ll z){update(id[x],id[x] + siz[x] - 1,z,1,N,1);}int main(){memset(head,-1,sizeof(head));scanf("%lld %lld %lld %lld",&N,&M,&R,&P);for(ll i = 1;i <= N;i++) scanf("%lld",&w[i]);for(ll i = 1;i < N;i++){ll u,v;scanf("%lld %lld",&u,&v);addnode(u,v);addnode(v,u);}dfs1(R,0,1);dfs2(R,R);for(ll i = 1;i <= N;i++){A[i] = w[rk[i]];}build(1,N,1);while(M--){ll op,x,y,z;scanf("%lld",&op);if(op == 1){scanf("%lld %lld %lld",&x,&y,&z);getupdate(x,y,z);}if(op == 2){scanf("%lld %lld",&x,&y);printf("%lld\n",getsum(x,y));}if(op == 3){scanf("%lld %lld",&x,&z);getsonupdate(x,z);}if(op == 4){scanf("%lld",&x);printf("%lld\n",getsonsum(x));}}return 0;}
#include <bits/stdc++.h>using namespace std;const int maxn = 100010;int T,n,m,np;int L[maxn*20],R[maxn*20],Sum[maxn*20],A[maxn],B[maxn],Root[maxn];int build(int l,int r){int rt = ++np;Sum[rt] = 0;if(l < r){int mid = (l + r) / 2;L[rt] = build(l,mid);R[rt] = build(mid + 1,r);}return rt;}int update(int pre,int l,int r,int x){int rt = ++np;L[rt] = L[pre],R[rt] = R[pre],Sum[rt] = Sum[pre] + 1;int mid = (l + r) / 2;if(l < r){if(x <= mid) L[rt] = update(L[pre],l,mid,x);else R[rt] = update(R[pre],mid + 1,r,x);}return rt;}int query(int u,int v,int l,int r,int k){if(l >= r) return l;int mid = (l + r) / 2;int x = Sum[L[v]] - Sum[L[u]];if(x >= k) return query(L[u],L[v],l,mid,k);else return query(R[u],R[v],mid + 1,r,k - x);}int main(){int T;scanf("%d",&T);while(T--){np = 0;scanf("%d %d",&n,&m);for(int i = 1;i <= n;i++){scanf("%d",&A[i]);B[i] = A[i];}sort(B + 1,B + 1 + n);int len = unique(B + 1,B + 1 + n) - (B + 1);Root[0] = build(1,len);for(int i = 1;i <= n;i++){int p = lower_bound(B + 1,B + 1 + len,A[i]) - B;Root[i] = update(Root[i - 1],1,len,p);}while(m--){int x,y,z;scanf("%d %d %d",&x,&y,&z);int p = query(Root[x - 1],Root[y],1,len,z);printf("%d\n",B[p]);}}return 0;}
线性基的性质:
1、原序列里面的任意一个数都可以由线性基里面的一些数异或得到。
2、线性基里面的任意一些数异或起来都不能得到0。
3、线性基里面的数的个数唯一,并且在保持性质一的前提下,数的个数是最少的。
struct LineBase{ll b[66];//上三角矩阵ll p[66];//对角矩阵int cnt;int max_b = 63;void init(){memset(b,0,sizeof(b));memset(p,0,sizeof(p));cnt = 0;}bool Insert(ll x)//插入{for(int i = max_b;i >= 0;i--){if((x>>i)&1){if(b[i] == 0){b[i] = x;break;}x = x^b[i];}}if(x > 0) cnt++;return (x > 0);}LineBase Merge(LineBase n1,LineBase n2)//线性基合并{LineBase ret = n1;for(int i = 0;i <= max_b;i++){if(n2.b[i]) ret.Insert(n2.b[i]);}return ret;}LineBase Merge2(LineBase A,LineBase B)//线性基求交{LineBase All,C,D;All.init();C.init();D.init();for(ll i = 60;i >= 0;i--){All.b[i] = A.b[i];D.b[i] = 1ll<<i;}for(ll i = 60;i >= 0;i--){if(B.b[i]){ll v = B.b[i],k = 0;bool can = true;for(ll j = 60;j >= 0;j--){if(v & (1ll<<j)){if(All.b[j]){v^=All.b[j];k^=D.b[j];}else{can = false;All.b[j] = v;D.b[j] = k;break;}}}if(can){ll v = 0;for(ll j = 60;j >= 0;j--){if(k & (1ll<<j)){v^=A.b[j];}}C.Insert(v);}}}return C;}ll queryMax(ll x)//求最大{ll ans = x;for(int i = max_b;i >= 0;i--){if((ans^b[i]) > ans) ans^=b[i];}return ans;}ll queryMin()//求最小{for(int i = 0;i < max_b;i++){if(b[i]) return b[i];}return 0;}void rebuild()//化为对角矩阵{for(int i = max_b;i >= 0;i--){for(int j = i - 1;j >= 0;j--){if(b[i]&(1ll<<j)) b[i]^=b[j];}}cnt = 0;for(int i = 0;i <= max_b;i++){if(b[i]) p[cnt++] = b[i];}}ll kthquery(ll k)//求第k大(必须先化为对角矩阵){ll ans = 0;if(k >= (1ll<<cnt)) return -1;for(int i = max_b;i >= 0;i--){if(k&(1ll<<i)) ans^=p[i];}return ans;}};
输入前几项数据,快速求解线性递推式的第n项。
#include <bits/stdc++.h>using namespace std;namespace linear_seq{#define rep(i,a,n) for(int i = a;i < n;i++)#define per(i,a,n) for(int i = n - 1;i >= a;i--)#define pb push_back#define mp make_pari#define all(x) (x).begin(),(x).end()#define fi first#define se second#define SZ(x) ((int)(x).size())typedef vector<int> VI;typedef pair<int,int> PII;typedef long long ll;const ll mod = 1e9 + 7;const int N = 100010;ll res[N],base[N],_c[N],_md[N];ll modpow(ll a,ll b,ll mod) {ll res = 1;a %= mod;for(;b;b>>=1){if(b&1)res = res*a%mod;a=a*a%mod;}return res;}vector<int> Md;void mul(ll *a,ll *b,ll k){rep(i,0,k+k) _c[i] = 0;rep(i,0,k) if(a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;for(int i = k+k-1;i>=k;i--) if(_c[i])rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;rep(i,0,k) a[i]=_c[i];}int solve(ll n,VI a,VI b){ll ans=0,pnt=0;int k=SZ(a);rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;Md.clear();rep(i,0,k) if(_md[i]!=0) Md.push_back(i);rep(i,0,k) res[i]=base[i]=0;res[0]=1;while((1ll<<pnt)<=n) pnt++;for(int p=pnt;p>=0;p--){mul(res,res,k);if((n>>p)&1){for(int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;}}rep(i,0,k) ans=(ans+res[i]*b[i])%mod;if(ans<0) ans+=mod;return ans;}VI BM(VI s){VI C(1,1),B(1,1);int L=0,m=1,b=1;rep(n,0,SZ(s)){ll d=0;rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;if(d==0) ++m;else if(2*L<=n){VI T=C;ll c=mod-d*modpow(b,mod-2,mod)%mod;while(SZ(C)<SZ(B)+m) C.pb(0);rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;L=n+1-L;B=T;b=d;m=1;}else{ll c=mod-d*modpow(b,mod-2,mod)%mod;while(SZ(C)<SZ(B)+m) C.pb(0);rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;++m;}}return C;}int gao(VI a,ll n){VI c=BM(a);c.erase(c.begin());rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));}}typedef long long ll;const int MOD = 1e9 + 7;ll n,k;ll dp[2050];ll powMod(ll a,ll b){ll res = 1;while(b){if(b % 2 == 1) res = res * a % MOD;a = a * a % MOD;b /= 2;}return res;}int main(){int T;scanf("%d",&T);while(T--){scanf("%lld %lld",&k,&n);if(n == -1){ll ans = 2;ans = ans * powMod(k + 1,MOD - 2) % MOD;printf("%lld\n",ans);continue;}ll p = powMod(k,MOD - 2);//把递推式的前2 * k项计算出来并放入vetor中vector<int>v;v.push_back(1);dp[0] = 1;for(int i = 1;i <= 2 * k;i++){dp[i] = 0;for(int j = i - 1;j >= max(0ll,i - k);j--){dp[i] = (dp[i] + dp[j] * p % MOD) % MOD;}v.push_back(dp[i]);}//调用函数计算得到第n项的值ll ans = linear_seq::gao(v,n);printf("%lld\n",ans);}return 0;}
ans * ans =(同余) n % p
#include <bits/stdc++.h>using namespace std;typedef long long ll;ll w;ll p;bool ok;ll powMod(ll a,ll b){ll res = 1;while(b){if(b&1) res = res * a % p;a = a * a % p;b /= 2;}return res;}struct QuadraticField{ll x,y;QuadraticField operator*(QuadraticField T){QuadraticField ans;ans.x = (this->x * T.x % p + this->y * T.y % p * w % p) % p;ans.y = (this->x * T.y % p + this->y * T.x % p) % p;return ans;}QuadraticField operator^(ll b){QuadraticField ans;QuadraticField a = *this;ans.x = 1;ans.y = 0;while(b){if(b & 1){ans = ans * a;b--;}b /= 2;a = a * a;}return ans;}};ll Lengender(ll a){ll ans = powMod(a,(p - 1) / 2);if(ans + 1 == p) return -1;else return ans;}ll GetW(ll n,ll a){return ((a * a - n) % p + p) % p;}ll Solve(ll n){ll a;if(p == 2) return n;if(Lengender(n) == -1) ok = false;srand((unsigned)time(NULL));while(1){a = rand() % p;w = GetW(n,a);if(Lengender(w) == -1) break;}QuadraticField ans,res;res.x = a;res.y = 1;ans = res ^ ((p + 1) / 2);return ans.x;}int main(){ll n,ans1,ans2;while(scanf("%lld %lld",&n,&p) != EOF){ok = true;n %= p;ans1 = Solve(n);ans2 = p - ans1;if(!ok) printf("-1\n");else printf("%lld %lld\n",ans1,ans2);}return 0;}