XIII Open Cup named after E.V. Pankratiev. GP of Ukraine
A. Automaton
后缀自动机可以得到$O(2n+1)$个状态,但是后缀自动机会拒绝接收所有不是$S$的子串的串,所以在建立后缀自动机的时候不复制节点即可得到$n+1$个状态的DFA。
- #include<stdio.h>
- #include<algorithm>
- #include<math.h>
- #include<string.h>
- #include<string>
- #include<vector>
- #include<set>
- #include<map>
- #include<queue>
- #include<time.h>
- #include<assert.h>
- #include<iostream>
- using namespace std;
- typedef long long LL;
- typedef pair<int,int>pi;
- const int Maxn=200020;
- int n,q,sz,last,len;
- int ml[Maxn],f[Maxn],ch[Maxn][26];
- vector<int>G[Maxn];
- string ss[Maxn];
- string s;
- void add(int c)
- {
- int p=last;
- if(ch[p][c])
- {
- int q=ch[p][c];
- if(ml[q]==ml[p]+1)last=q;
- else
- {
- int nq=++sz;
- memcpy(ch[nq],ch[q],sizeof(ch[q]));
- ml[nq]=ml[p]+1;
- last=nq;
- f[nq]=f[q];
- f[q]=nq;
- for(;p&&ch[p][c]==q;p=f[p])ch[p][c]=nq;
- }
- }
- else
- {
- int np=++sz;last=np;
- memset(ch[np],0,sizeof ch[np]);
- ml[np]=ml[p]+1;
- for(;p&&!ch[p][c];p=f[p])ch[p][c]=np;
- if(!p){f[np]=1;return;}
- int q=ch[p][c];
- f[np]=q;return;//
- if(ml[q]==ml[p]+1){f[np]=q;return;}
- int nq=++sz;
- memcpy(ch[nq],ch[q],sizeof(ch[q]));
- ml[nq]=ml[p]+1;
- f[nq]=f[q];
- f[q]=f[np]=nq;
- for(;p&&ch[p][c]==q;p=f[p])ch[p][c]=nq;
- }
- }
- void init(){
- sz=1;memset(ch[sz],0,sizeof ch[sz]);
- }
- void insert(string &s)
- {
- last=1;
- for(int i=0;i<s.size();i++)
- {
- add(s[i]-'a');
- }
- }
- struct Node{
- int u,v;
- char c;
- Node(){}
- Node(int u,int v,char c):u(u),v(v),c(c){}
- };
- bool check(int st){
- int cur=1;
- for(int i=st;i<s.size();i++){
- if(!ch[cur][s[i]-'a'])return 0;
- cur=ch[cur][s[i]-'a'];
- }
- return 1;
- }
- int main(){
- while(cin>>s){
- //s.assign(20,'a');
- //for(int i=0;i<20;i++)s[i]=rand()%5+s[i];
- memset(ch,0,sizeof ch);
- init();
- insert(s);
- vector<Node>rep;
- for(int i=1;i<=sz;i++){
- for(int j=0;j<26;j++){
- if(ch[i][j])rep.push_back(Node(i,ch[i][j],j+'a'));
- }
- }
- /*
- for(int i=0;i<s.size();i++){
- if(!check(i)){
- puts("wa");
- cout<<s<<endl;
- printf("%d\n",i);
- while(1);
- }
- }
- */
- printf("%d %d\n",sz,(int)rep.size());
- for(int i=0;i<rep.size();i++)printf("%d %d %c\n",rep[i].u,rep[i].v,rep[i].c);
- }
- return 0;
- }
B. Beinz
用Lucas定理计算组合数即可,时间复杂度$O(p+t\log n)$。
- #include<stdio.h>
- #include<algorithm>
- #include<math.h>
- #include<string.h>
- #include<string>
- #include<vector>
- #include<set>
- #include<map>
- #include<queue>
- #include<time.h>
- #include<assert.h>
- #include<iostream>
- using namespace std;
- typedef long long LL;
- typedef pair<int,int>pi;
- const int mod=1e9+7;
- const int Maxn=1002000;
- int fac[Maxn],rev[Maxn];
- int C(int x,int y){
- if(x<y||y<0)return 0;
- return 1LL*fac[x]*rev[y]%mod*rev[x-y]%mod;
- }
- int main(){
- int k,p,t;
- LL n;
- fac[0]=fac[1]=rev[0]=rev[1]=1;
- for(int i=2;i<Maxn;i++)fac[i]=1LL*i*fac[i-1]%mod;
- for(int i=2;i<Maxn;i++)rev[i]=1LL*(mod-mod/i)*rev[mod%i]%mod;
- for(int i=2;i<Maxn;i++)rev[i]=1LL*rev[i-1]*rev[i]%mod;
- while(scanf("%d%d%d",&k,&p,&t)!=EOF){
- while(t--){
- scanf("%lld",&n);
- LL ans=1;
- while(n){
- ans=1LL*ans*C(n%p+k-1,k-1)%mod;
- n/=p;
- }
- printf("%lld\n",ans);
- }
- }
- return 0;
- }
C. Cutting
首先将串插入Trie中,可以去掉一些冗余状态。
设$dp[l][r][x][y]$表示$[l,r]$这个区间切成串$x$的前缀$y$的最少步数,可以枚举下一个匹配点转移。
设$f[l][r]$表示$[l,r]$消完的最小步数,可以暴力转移求解。
在计算$dp$的时候加上可行性剪枝即可,复杂度达不到理论上界$O(n^5)$。
- #include <bits/stdc++.h>
- using namespace std ;
- typedef long long LL ;
- typedef pair < int , int > pii ;
- #define clr( a , x ) memset ( a , x , sizeof a )
- const int N = 105 ;
- const int MAXN = 10005 ;
- const int INF = 0x3f3f3f3f ;
- int node[MAXN][26] ;
- int word[MAXN] ;
- char s[N] , p[N] ;
- int dp[N][MAXN] ;
- int jump[N][26] , pre[26] ;
- int f[N][N] ;
- int n , m , cur ;
- int newnode () {
- clr ( node[cur] , 0 ) ;
- word[cur] = 0 ;
- return cur ++ ;
- }
- void insert ( char s[] ) {
- int now = 0 ;
- for ( int i = 0 ; s[i] ; ++ i ) {
- int x = s[i] - 'a' ;
- if ( !node[now][x] ) node[now][x] = newnode () ;
- now = node[now][x] ;
- }
- word[now] = 1 ;
- }
- void solve () {
- n = strlen ( s + 1 ) ;
- for ( int i = 0 ; i < 26 ; ++ i ) {
- pre[i] = n + 1 ;
- }
- for ( int i = n ; i >= 0 ; -- i ) {
- for ( int j = 0 ; j < 26 ; ++ j ) {
- jump[i][j] = pre[j] ;
- }
- pre[s[i] - 'a'] = i ;
- }
- cur = 0 ;
- newnode () ;
- for ( int i = 0 ; i < m ; ++ i ) {
- scanf ( "%s" , p ) ;
- insert ( p ) ;
- }
- clr ( f , INF ) ;
- for ( int l = n ; l >= 1 ; -- l ) {
- clr ( dp , INF ) ;
- dp[l - 1][0] = 0 ;
- for ( int r = l ; r <= n ; ++ r ) {
- for ( int now = 0 ; now < cur ; ++ now ) if ( dp[r - 1][now] < INF ) {
- for ( int i = 0 ; i < 26 ; ++ i ) if ( node[now][i] ) {
- int nxt = node[now][i] ;
- int x = jump[r - 1][i] ;
- while ( x <= n ) {
- int tmp = r <= x - 1 ? f[r][x - 1] : 0 ;
- dp[x][nxt] = min ( dp[x][nxt] , dp[r - 1][now] + tmp ) ;
- if ( word[nxt] ) f[l][x] = min ( f[l][x] , dp[x][nxt] + 1 ) ;
- x = jump[x][i] ;
- }
- }
- }
- }
- for ( int r = l ; r <= n ; ++ r ) {
- for ( int i = l ; i < r ; ++ i ) {
- f[l][r] = min ( f[l][r] , f[l][i] + f[i + 1][r] ) ;
- }
- }
- }
- printf ( "%d\n" , f[1][n] ) ;
- }
- int main () {
- while ( ~scanf ( "%s%d" , s + 1 , &m ) ) solve () ;
- return 0 ;
- }
D. Disclosure
对于一条边$x->y$,若去掉之后$x$不能到达$y$,那么它是必需的。
首先拓扑排序求出拓扑序,然后按照终点拓扑序为第一关键字,起点拓扑序为第二关键字从小到大加边。
对于每个点,维护一个bitset,表示当前从哪些点可以到达自己。
时间复杂度$O(\frac{nm}{32})$。
- #include<cstdio>
- #include<bitset>
- #include<algorithm>
- using namespace std;
- typedef pair<int,int>P;
- const int N=50002,M=50002;
- int n,m,i,j,x,y,d[N],g[N],g2[N],v[M],v2[M],nxt[M],nxt2[M],ed,h,t,q[N],ans;bitset<N>f[N];P b[M];
- inline void add(int x,int y){d[y]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
- inline void add2(int x,int y){v2[++ed]=y;nxt2[ed]=g2[x];g2[x]=ed;}
- int main(){
- scanf("%d%d",&n,&m);
- for(i=1;i<=n;i++)f[i][i]=1;
- while(m--)scanf("%d%d",&x,&y),add(x,y);
- for(ed=0,i=h=1;i<=n;i++)if(!d[i])q[++t]=i;
- while(h<=t)for(i=g[x=q[h++]];i;add2(v[i],x),i=nxt[i])if(!(--d[v[i]]))q[++t]=v[i];
- for(i=1;i<=n;i++)for(j=g2[x=q[i]];j;f[x]|=f[v2[j]],j=nxt2[j])if(!f[x][v2[j]])b[++ans]=P(v2[j],x);
- sort(b+1,b+ans+1);
- for(i=1;i<=ans;i++)printf("%d %d\n",b[i].first,b[i].second);
- return 0;
- }
E. Embedded circles
如果询问$i$的范围完全包含询问$j$,那么$i$向$j$连边,这样可以得到一棵树。
因为题目的限制,所以它给出的是这棵树的dfs序列。
维护一个栈,按深度维护当前询问到根的路径,每次读入一个新的询问,如果它的圆心不被栈顶询问包含,那么弹栈,这样就可以找到当前询问的父亲。
每次弹栈的时候计算被弹询问的答案,为了保证复杂度均摊线性,需要找到若干个属于它的且不属于它任何孩子的一个起点,然后从这些起点开始BFS染色。
每次BFS染色出界的时候,在栈中二分查找出深度最大的包含了这个位置的询问,那么这个点就是那个询问的一个可能的起点。
时间复杂度$O(RC+Q\log Q)$。
- #include<cstdio>
- const int N=2010,M=1000010,E=N*N*4;
- int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
- int n,m,i,j,cq,e[M][3],q[M],t,ans[M];char a[N][N];
- int que[N*N],head,tail;bool vis[N][N];
- int g[M],v[E],nxt[E],ed;
- long long all;
- inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
- inline int sqr(int x){return x*x;}
- inline bool check(int x,int y,int p){
- return sqr(x-e[p][0])+sqr(y-e[p][1])<=e[p][2];
- }
- inline void add(int x,int y){
- int l=1,r=t-1,mid,o=0;
- while(l<=r)if(check(x,y,q[mid=(l+r)>>1]))l=(o=mid)+1;else r=mid-1;
- if(o)v[++ed]=x<<11|y,nxt[ed]=g[q[o]],g[q[o]]=ed;
- }
- inline void bfs(int o,int x,int y){
- if(vis[x][y])return;
- que[head=tail=1]=x<<11|y;
- vis[x][y]=1;
- while(head<=tail){
- x=que[head++];
- y=x&2047;x>>=11;
- ans[o]+=a[x][y];
- for(int d=0;d<4;d++){
- int nx=x+dx[d],ny=y+dy[d];
- if(nx<1||nx>n||ny<1||ny>m||vis[nx][ny])continue;
- if(check(nx,ny,o)){
- que[++tail]=nx<<11|ny;
- vis[nx][ny]=1;
- }else{
- add(nx,ny);
- }
- }
- }
- }
- inline void pop(){
- int o=q[t];
- bfs(o,e[o][0],e[o][1]);
- for(int i=g[o];i;i=nxt[i])bfs(o,v[i]>>11,v[i]&2047);
- ans[q[--t]]+=ans[o];
- }
- int main(){
- read(n),read(m);
- for(i=1;i<=n;i++){
- scanf("%s",a[i]+1);
- for(j=1;j<=m;j++)a[i][j]-='0';
- }
- read(cq);
- for(i=1;i<=cq;q[++t]=i++){
- read(e[i][0]),read(e[i][1]),read(e[i][2]);e[i][2]*=e[i][2];
- while(t&&!check(e[i][0],e[i][1],q[t]))pop();
- }
- while(t)pop();
- for(i=1;i<=cq;i++)all+=ans[i];
- printf("%lld",all);
- return 0;
- }
F. False figures
留坑。
G. Grouping
首先将$a$从小到大排序,那么相当于要求把$a$分成$k$段,每段计算所有数到区间中位数的差的绝对值之和,要求最小化这个和。
因为$a$有序,所以计算一段的代价可以用前缀和做到$O(1)$。
设$f[i][j]$表示前$j$个数分成$i$段的最小代价,那么$f[i][j]=\min(f[i-1][k]+cost(k+1,j))$,$(0\leq k<j)$。
转移具有决策单调性,所以可以分治求解。
时间复杂度$O(nk\log n)$。
- #include<cstdio>
- #include<algorithm>
- const int N=5005,inf=2100000000;
- typedef unsigned int U;
- int n,m,i,o,a[N],s[N];U f[2][N];
- inline U cal(int l,int r){
- int m=(l+r)>>1;
- return (m+m-l-r)*a[m]-s[m]+s[l-1]+s[r]-s[m-1];
- }
- void dp(int l,int r,int dl,int dr){
- int m=(l+r)>>1,dm=dl;
- U tmp=inf;
- for(int i=dl;i<=dr&&i<m;i++){
- U now=f[o^1][i]+cal(i+1,m);
- if(now<tmp)tmp=now,dm=i;
- }
- f[o][m]=tmp;
- if(l<m)dp(l,m-1,dl,dm);
- if(r>m)dp(m+1,r,dm,dr);
- }
- int main(){
- scanf("%d%d",&n,&m);
- for(i=1;i<=n;i++)scanf("%d",&a[i]);
- std::sort(a+1,a+n+1);
- for(i=1;i<=n;i++)s[i]=s[i-1]+a[i];
- for(i=1;i<=n;i++)f[0][i]=inf;
- while(m--){
- o^=1;
- for(i=0;i<=n;i++)f[o][i]=inf;
- dp(1,n,0,n);
- }
- printf("%u",f[o][n]);
- return 0;
- }
H. Hidden triangles
留坑。
I. Interactive
用FFT加速多项式乘法即可,注意需要开long double。
时间复杂度$O(n\log n)$。
- #include<cstdio>
- #include<cmath>
- #include<algorithm>
- using namespace std;
- const int N=131100;
- int n,i,j,k,pos[N],a[N],b[N];long long c[N];
- namespace FFT{
- struct comp{
- long double r,i;comp(long double _r=0,long double _i=0){r=_r,i=_i;}
- comp operator+(const comp&x){return comp(r+x.r,i+x.i);}
- comp operator-(const comp&x){return comp(r-x.r,i-x.i);}
- comp operator*(const comp&x){return comp(r*x.r-i*x.i,r*x.i+i*x.r);}
- comp conj(){return comp(r,-i);}
- }A[N],B[N];
- const long double pi=acos(-1.0);
- void FFT(comp a[],int n,int t){
- for(int i=1;i<n;i++)if(i<pos[i])swap(a[i],a[pos[i]]);
- for(int d=0;(1<<d)<n;d++){
- int m=1<<d,m2=m<<1;
- long double o=pi*2/m2*t;comp _w(cos(o),sin(o));
- for(int i=0;i<n;i+=m2){
- comp w(1,0);
- for(int j=0;j<m;j++){
- comp&A=a[i+j+m],&B=a[i+j],t=w*A;
- A=B-t;B=B+t;w=w*_w;
- }
- }
- }
- if(t==-1)for(int i=0;i<n;i++)a[i].r/=n;
- }
- void mul(int*a,int*b,long long*c){
- int i,j;
- for(i=0;i<k;i++)A[i]=comp(a[i],b[i]);
- FFT(A,k,1);
- for(i=0;i<k;i++){
- j=(k-i)&(k-1);
- B[i]=(A[i]*A[i]-(A[j]*A[j]).conj())*comp(0,-0.25);
- }
- FFT(B,k,-1);
- for(i=0;i<k;i++)c[i]=(long long)(B[i].r+0.5);
- }
- }
- int main(){
- scanf("%d",&n);
- for(k=1;k<n;k<<=1);k<<=1;
- j=__builtin_ctz(k)-1;
- for(i=0;i<k;i++)pos[i]=pos[i>>1]>>1|((i&1)<<j);
- for(i=0;i<n;i++)scanf("%d",&a[i]);
- for(i=0;i<n;i++)scanf("%d",&b[i]);
- FFT::mul(a,b,c);
- for(i=0;i<n+n-1;i++)printf("%lld%c",c[i],i<n+n-2?' ':'\n');
- return 0;
- }
J. Joinery
枚举长方体的$8$个端点,然后枚举$6$个面,在每个面上三分套三分查找表面距离最远的点即可。
- #include<cstdio>
- #include<cmath>
- #include<algorithm>
- using namespace std;
- double ans,r;
- const double eps=1e-8;
- double LL,WW,HH;
- struct P{
- double x,y,z;
- P(){}
- P(double _x,double _y,double _z){x=_x,y=_y,z=_z;}
- }a[8];
- void turn(int i,int j,double x,double y,double z,double x0,double y0,double L,double W,double H){
- if(z==0){
- double R=x*x+y*y;
- if(R<r)r=R;
- }else{
- if(i>=0&&i<2)turn(i+1,j,x0+L+z,y,x0+L-x,x0+L,y0,H,W,L);
- if(j>=0&&j<2)turn(i,j+1,x,y0+W+z,y0+W-y,x0,y0+W,L,H,W);
- if(i<=0&&i>-2)turn(i-1,j,x0-z,y,x-x0,x0-H,y0,H,W,L);
- if(j<=0&&j>-2)turn(i,j-1,x,y0-z,y-y0,x0,y0-H,L,H,W);
- }
- }
- double cal(double x1,double y1,double z1,double x2,double y2,double z2){
- double L=LL,W=WW,H=HH;
- if(fabs(z1)>eps&&fabs(z1-H)>eps)if(fabs(y1)<eps||fabs(y1-W)<eps)
- swap(y1,z1),swap(y2,z2),swap(W,H);
- else
- swap(x1,z1),swap(x2,z2),swap(L,H);
- if(fabs(z1-H)<eps)z1=0,z2=H-z2;
- r=1e20;
- turn(0,0,x2-x1,y2-y1,z2,-x1,-y1,L,W,H);
- return r;
- }
- double solvexy(double x,double y,double z,double A,double B,double C){
- double l=0,r=C,m1,m2,s1,s2;
- double ret=0;
- while(l+eps<r){
- double len=(r-l)/3.0;
- m1=l+len;
- m2=r-len;
- s1=cal(x,y,z,A,B,m1);
- s2=cal(x,y,z,A,B,m2);
- ret=max(ret,max(s1,s2));
- if(s1>s2)r=m2;else l=m1;
- }
- return ret;
- }
- double solvexz(double x,double y,double z,double A,double B,double C){
- double l=0,r=B,m1,m2,s1,s2;
- double ret=0;
- while(l+eps<r){
- double len=(r-l)/3.0;
- m1=l+len;
- m2=r-len;
- s1=cal(x,y,z,A,m1,C);
- s2=cal(x,y,z,A,m2,C);
- ret=max(ret,max(s1,s2));
- if(s1>s2)r=m2;else l=m1;
- }
- return ret;
- }
- double solvex(double x,double y,double z,double A,double B,double C){
- double l=0,r=B,m1,m2,s1,s2;
- double ret=0;
- while(l+eps<r){
- double len=(r-l)/3.0;
- m1=l+len;
- m2=r-len;
- s1=solvexy(x,y,z,A,m1,C);
- s2=solvexy(x,y,z,A,m2,C);
- ret=max(ret,max(s1,s2));
- if(s1>s2)r=m2;else l=m1;
- }
- return ret;
- }
- double solvey(double x,double y,double z,double A,double B,double C){
- double l=0,r=A,m1,m2,s1,s2;
- double ret=0;
- while(l+eps<r){
- double len=(r-l)/3.0;
- m1=l+len;
- m2=r-len;
- s1=solvexy(x,y,z,m1,B,C);
- s2=solvexy(x,y,z,m2,B,C);
- ret=max(ret,max(s1,s2));
- if(s1>s2)r=m2;else l=m1;
- }
- return ret;
- }
- double solvez(double x,double y,double z,double A,double B,double C){
- double l=0,r=A,m1,m2,s1,s2;
- double ret=0;
- while(l+eps<r){
- double len=(r-l)/3.0;
- m1=l+len;
- m2=r-len;
- s1=solvexz(x,y,z,m1,B,C);
- s2=solvexz(x,y,z,m2,B,C);
- ret=max(ret,max(s1,s2));
- if(s1>s2)r=m2;else l=m1;
- }
- return ret;
- }
- int main(){
- int i,j;
- double L,H,W;
- scanf("%lf%lf%lf",&L,&W,&H);
- a[0]=P(0,0,0);
- a[1]=P(0,0,H);
- a[2]=P(0,W,0);
- a[3]=P(0,W,H);
- a[4]=P(L,0,0);
- a[5]=P(L,0,H);
- a[6]=P(L,W,0);
- a[7]=P(L,W,H);
- LL=L;
- WW=W;
- HH=H;
- for(i=0;i<8;i++)for(j=0;j<8;j++)
- ans=max(ans,cal(a[i].x,a[i].y,a[i].z,a[j].x,a[j].y,a[j].z));
- for(i=0;i<8;i++){
- ans=max(ans,solvex(a[i].x,a[i].y,a[i].z,0,W,H));
- ans=max(ans,solvex(a[i].x,a[i].y,a[i].z,L,W,H));
- ans=max(ans,solvey(a[i].x,a[i].y,a[i].z,L,0,H));
- ans=max(ans,solvey(a[i].x,a[i].y,a[i].z,L,W,H));
- ans=max(ans,solvez(a[i].x,a[i].y,a[i].z,L,W,0));
- ans=max(ans,solvez(a[i].x,a[i].y,a[i].z,L,W,H));
- }
- double ret=sqrt(ans);
- printf("%.13f",ret);
- return 0;
- }
XIII Open Cup named after E.V. Pankratiev. GP of Ukraine的更多相关文章
- XIII Open Cup named after E.V. Pankratiev. GP of Asia and South Caucasus
A. RPG 首先计算出每个技能对于每个属性值的可行区间,若区间为空则不合法. 枚举两个技能,以及每个属性值,根据区间的关系可以得到哪个必须要在另一个之前学,连边看看是否有环即可. 时间复杂度$O(n ...
- XIII Open Cup named after E.V. Pankratiev. GP of Azov Sea
A. Freestyle 如果逆序对为$0$,那么先手必败. 因为每次只能翻转长度为$4k+2$和$4k+3$的区间,所以每次操作之后逆序对的奇偶性一定会发生改变. 因此如果逆序对个数为偶数,则先手必 ...
- XIII Open Cup named after E.V. Pankratiev. GP of America
A. Explosions 注意到将炸弹按坐标排序后,每个炸弹直接引爆和间接引爆的都是连续的一段区间,因此只需要求出每个炸弹能间接炸到的最左和最右的炸弹即可. 建立图论模型,炸弹$i$向炸弹$j$连单 ...
- XIII Open Cup named after E.V. Pankratiev. GP of Saratov
A. Box Game 注意到局面总数不超过$50000$,而且每次操作都会改变石子的奇偶性,因此按奇偶可以将状态建成二分图,然后求出最大匹配. 如果状态数是偶数,那么先手必胜,策略就是每次走匹配边, ...
- XIII Open Cup named after E.V. Pankratiev. GP of SPb
A. Graph Coloring 答案为$1$很好判,为$2$只需要二分图染色,对于$3$,首先爆搜哪些边要染成第$3$种颜色,然后二分图染色判定即可. B. Decimal Fraction 枚举 ...
- XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
A. Associated Vertices 首先求出SCC然后缩点,第一次求出每个点能到的点集,第二次收集这些点集即可,用bitset加速,时间复杂度$O(\frac{nm}{64})$. #inc ...
- XV Open Cup named after E.V. Pankratiev. GP of Tatarstan
A. Survival Route 留坑. B. Dispersed parentheses $f[i][j][k]$表示长度为$i$,未匹配的左括号数为$j$,最多的未匹配左括号数为$k$的方案数. ...
- XVII Open Cup named after E.V. Pankratiev. GP of SPb
A. Array Factory 将下标按前缀和排序,然后双指针,维护最大的右边界即可. #include<cstdio> #include<algorithm> using ...
- XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
A. (a, b)-Tower 当指数大于模数的时候用欧拉定理递归计算,否则直接暴力计算. #include<cstdio> #include<algorithm> #incl ...
随机推荐
- php无刷新上传图片和文件
核心思想:通过Html的iframe标签属性操作顶级窗口,再用php动态无刷新上传图片文件. 示例如下: demo |------uploads #存放上传的文件 |------index.php | ...
- Web jquery表格组件 JQGrid 的使用 - 6.准备工作 & Hello JQGrid
系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...
- ecshop 实现购物车退出不清空
ecshop模板在使用过程中会遇到会员退出再登陆时购物车里面的商品会被清空掉的,通过ecshop开发中心的技术,整理的文档,对程序做简单修改即可实现会员退出不清空购物车 ECShop版本:V2.7.3 ...
- apache启动出错原因举例
这是我这两天频繁遇到的问题.Apache服务器还真是问题少年!任何点改动都可能导致它无法使用. 原因一:80端口占用例如IIS,另外就是迅雷.我的apache服务器就是被迅雷害得无法启用! 原因二:软 ...
- 浅谈MVC中路由
引言 学习ASP.NET MVC 路由这一关是肯定必不可少的.这一节,我们就来简单介绍下MVC中的路由机制.简单的路由机制相信大家都已了解,这一节主要介绍路由中很少使用的部分. 使用静态URL片段 在 ...
- IK分词器 整合solr4.7 含同义词、切分词、停止词
转载请注明出处! IK分词器如果配置成 <fieldType name="text_ik" class="solr.TextField"> < ...
- silverlight_容器
Canvas絕對佈局 定位Canvas.Top.Canvas.Left ZIndex屬性 若制定2個控制項重疊,那麼後聲明控制項會覆蓋先聲明的控制項.此時可以使用Canvas.ZIndex屬性來改變它 ...
- PHP exec/system启动windows应用程序,执行.bat批处理,执行cmd命令
exec 或者 system 都可以调用cmd 的命令 直接上代码: <?php /** 打开windows的计算器 */ exec('start C:WindowsSystem32calc.e ...
- Linux网络下载命令 wget 简介
wget 是一个命令行的下载工具.对于我们这些 Linux 用户来说,几乎每天都在使用它.下面为大家介绍几个有用的 wget 小技巧,可以让你更加高效而灵活的使用 wget. $ wget -r -n ...
- jquery----中级函数
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...