长安大学第二届ACM程序设计竞赛校赛 题解

A Count Circles

描述
Stupid Aguin feels confused while reading. The book shows following equations:
6=9 , 8=1010 , 144=75 , 690=801
Stupid Aguin doesn’t know why and he asks RoyYuan for help. RoyYuan tells Aguin that he only needs to count circles in each number. Notice that 0 , 6 and 9 have one circle, and 8 has two circles. For example, both 690 and 801 have 3 circles, so 690 = 801.

However, Aguin is too stupid to count circles in each number, please help him.

输入
The first line contains an integer number T, the number of test cases.

i-th of each next T lines contains an integer number x(0≤x≤109).

输出
For each test case print a number, the number of circles in x.

#include<bits/stdc++.h>
using namespace std;

int a[]={1,0,0,0,0,0,1,0,2,1};
int T;
int n,ans;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        if(n==0)
        {
            printf("1\n");
            continue;
        }
        ans=0;
        while(n>0)
        {
            ans+=a[n%10];
            n/=10;
        }
        printf("%d\n",ans);
    }
    return 0;
}

B Boys and Girls

描述
AA is a kindergarten teacher, there are n boys and n girls in her class. Chairs in the classroom are put in a row, children select their seats according to their own preferences. However, AA wants to make boys and girls sit alternately. That is to say, if n=2, ‘B’ said a boy and ‘G’ said a girl, she wants her children sit like “BGBG” or “GBGB”. So she decides to make some changes, each time she chooses two adjacent children and swap their seats. Now she wants to know how many times she needs to swap at least.

输入
The first line contains an integer number T, the number of test cases.

For each test case :

The first line contains an integer n(1≤n≤105), the number of boys and girls.

The next line contains a string s consists of ‘B’ and ‘G’, representing the initial seats of children.

It’s guaranteed that |s|=2n and both ‘B’ and ‘G’ appear exactly n times in the string s.

输出
For each test case print a number, the minimum number of times required.

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
char s[200001];
long long solve(char ch)
{
    long long ans=0,rest=0;
    for(int i=0;s[i];i++){
        if(s[i]==ch){ans+=abs(rest);rest--;}
        else rest++;
    }
    return ans;
}
int main()
{
    int tt;
    scanf("%d",&tt);
    while(tt--){
        int n;
        scanf("%d%s",&n,s);
        long long ans1=solve('B');
        long long ans2=solve('G');
        printf("%lld\n",min(ans1,ans2));
    }
}

C Roses

描述
The Little Prince has n roses in his garden, which can be described as a 2-dimensional plane. The ith of the roses has the coordinate (xi, yi).It’s raining recently, to protect the roses, the Little Prince plans to arrange two umbrellas(overlapping is allowed) to cover all the roses. The area covered by one umbrella is a circle, the Little Prince can determine the sizes of two umbrellas(not necessarily the same) and he can also choose any positions to place these two umbrellas. Meanwhile, in order not to block too much sunshine after the rain, he wants to minimize the covered areas.

Help the Little Prince to calculate the minimized covered areas that satisfy the condition.

输入
The first line contains an integer number T, the number of test cases.

For each test case :

The first line contains an integer n(1≤n≤50), the number of roses.

The following n lines, each contains two integers xi, yi(|xi|,|yi|≤104), the coordinate of the ith rose.

It’s guaranteed that no coordinates coincide.

输出
For each test case print the minimum covered areas, round to two decimal places.

枚举其中一个圆,剩下最小圆覆盖

D Arrays

描述
Given two arrays A and B, both of them have n elements. Then there are m queries, each of which contains four integers: L, R, x, y. For each query, you are required to count different indexes k∈[L,R], that satisfy A[k]≥x and B[k]≥y.

输入
The first line contains an integer number T, the number of test cases.

For each test case :

The first line contains two integers n, m(1≤n,m≤105).

The second line contains n integers Ai.

The third line contains n integers Bi.

i-th of each next m lines contains four integers L, R, x, y(1≤L≤R≤n,1≤x,y≤105).

输出
For each query print the answer.

三维偏序

#include<bits/stdc++.h>
using namespace std;
#define Rep(i,n) for(int i=0;i<n;i++)
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define pb push_back
#define MEM(f) memset(f,0,sizeof(f));
#define MAXN (523456+10)    
int T;
int n,m,a[MAXN],b[MAXN];
int read() {
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
typedef long long ll;
struct BIT{
    ll f[MAXN],n;
    void mem() {
        MEM(f); n=100000;
    }
    void add(int x,int v) {
        for(int i=x;i<=n;i+=i&(-i)) 
            f[i]+=v;
    }
    ll qur(int x) {
        ll v=0;
        for(int i=x;i;i-=i&(-i)) {
            v+=f[i];
        }
        return v;
    }
}Tr;
int ans[MAXN];
struct com{
    int d,id,r,x,y;
    com(){}
    com(int _d,int _id,int _r,int _x,int _y):d(_d),id(_id),r(_r),x(_x),y(_y){}
    friend bool operator<(com a,com b) {
        if (a.r^b.r) return a.r<b.r;
        return a.d<b.d;
    }
}ask[MAXN],temp[MAXN];
int cmp2(com a,com b) {
    return a.x>b.x;
}
void cdq(int l,int r) {
    if(l==r) return;
    int m=(l+r)/2;
    {
        Fork(i,l,r) temp[i]=ask[i];
        sort(temp+l,temp+m+1,cmp2);
        sort(temp+m+1,temp+r+1,cmp2);

        int p1=l,p2=m+1;
        Fork(i,l,r) {
            int now=0;
            if (p2>r) now=p1++;
            else if (p1>m) now=p2++;
            else if (temp[p1].x<temp[p2].x) now=p2++;
            else if (temp[p1].x>temp[p2].x) now=p1++;
            else now=p1++;
            if (now<=m&&temp[now].d==-2) Tr.add(temp[now].y,1);
            else if (now>m) {
                ans[temp[now].id]+=temp[now].d*(Tr.qur(100000)-Tr.qur(temp[now].y-1));
            }
        }
        Fork(i,l,m) if (temp[i].d==-2) Tr.add(temp[i].y,-1);

    }
    cdq(l,m);
    cdq(m+1,r);
}
int main()
{
//  freopen("D.in.cpp","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        MEM(ans) Tr.mem();
        scanf("%d%d",&n,&m);
        For(i,n) a[i]=read();
        For(i,n) b[i]=read();
        int tot=0;
        For(i,n) ask[++tot]=com(-2,0,i,a[i],b[i]);
        For(i,m) {
            int l=read(),r=read(),x=read(),y=read();
            ask[++tot]=com(1,i,r,x,y);
            ask[++tot]=com(-1,i,l-1,x,y);
        }
        sort(ask+1,ask+1+tot);
        cdq(1,tot);

        For(i,m) {
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}

E Colorful Ribbon

描述
Lizishu has a colorful ribbon, which can be expressed as a string consists of only lowercase letters, and each letter represents a color.

Now she wants to divide the ribbon into several parts so that no color appears more than one time in each part.

Tell her how many different ways can she divide the ribbon, output the answer modulo 109+7.

输入
The first line contains an integer number T, the number of test cases.

i-th of each next T lines contains a string s consists of lowercase letters (1≤|s|≤105).

输出
For each test case print the answer modulo 109+7.

#include<bits/stdc++.h>
using namespace std;
int T;
const int mod=1e9+7;
const int maxn=100005;
int dp[maxn],sum[maxn];
char s[maxn];
int a[27][maxn];
int cnt[27];
int dd;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        dd=0;
        scanf("%s",s+1);
        int n=strlen(s+1);
        for(int i=1;i<=26;i++)
        {
            cnt[i]=0;
            a[i][0]=0;
        }
        for(int i=1;i<=n;i++)
        {
            dp[i]=sum[i]=0;
            int t=s[i]-96;
            cnt[t]++;
            a[t][cnt[t]]=i;
        }
        for(int i=1;i<=26;i++)cnt[i]=0;
        sum[0]=1;
        for(int i=1;i<=n;i++)
        {
            int t=s[i]-96;
            int k=a[t][cnt[t]];
            k=max(k,dd);dd=k;
            cnt[t]++;
            int temp=(k==0?0:sum[k-1]);
            dp[i]=(sum[i-1]-temp+mod)%mod;
            sum[i]=(sum[i-1]+dp[i])%mod;
        }
        printf("%d\n",dp[n]);
    }
    return 0;
}

F XOR-mean

描述
As we all know, the mean of two integers A and B is \frac{A + B}{2}.Similarly, let’s define XOR-mean of two non-negative integers A and B as \left \lfloor \frac{A \bigoplus B} {2} \right \rfloor(\bigoplus is the XOR operation, \left \lfloor x \right \rfloor is the integer part of x).Given an array C of length n, count different triples (i, j, k) that satisfy 1 \leq i < j < k \leq n and C[j] = \left \lfloor \frac{C[i] \bigoplus C[k]} {2} \right \rfloor.

输入
The first line contains an integer number T, the number of test cases.

For each test case :

The first line contains an integer n(1 \leq n \leq 50000).

The second line contains n integers C[i](0 \leq C[i] \leq 50000).

输出
For each query print the answer.

分块FWT 需要分4种情况讨论

版本1(容斥):

#include<bits/stdc++.h>
using namespace std;
#define Rep(i,n) for(int i=0;i<n;i++)
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define pb push_back
#define MEM(f) memset(f,0,sizeof(f));
#define MAXN (523456+10)    
#define LL long long
int T;
int n,a[MAXN];
int read() {
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
#define N (65535)
typedef long long ll;
void fwt(LL a[],int n,bool on){
    for(int d=1;d<n;d<<=1){
        for(int k=d<<1,i=0;i<n;i+=k){
            for(int j=0;j<d;j++){
                LL x=a[i+j],y=a[i+j+d];
                if(on){
                    a[i+j]=(x+y);
                    a[i+j+d]=(x-y);
                }
                else{
                    a[i+j]=(x+y)/2;
                    a[i+j+d]=(x-y)/2;
                }
            }
        }
    }
}
#define MAXN (1000000)
ll a2[1000000],a3[1000000];
void work(LL a[]) {
    fwt(a,65535,1);
    Rep(i,65536) a[i]=a[i]*a[i];
    fwt(a,65535,0);
    MEM(a2);
    Rep(i,65536) a2[i/2]+=a[i];
    Rep(i,65536) a[i]=a2[i];


}
void work2(LL a[]) {
    fwt(a,65535,1);
    Rep(i,65536) a3[i]=a[i];

    Rep(i,65536) a[i]=a[i]*a[i];
    fwt(a,65535,0);
    MEM(a2);
    Rep(i,65536) a2[i/2]+=a[i];
    fwt(a2,65535,1);

    Rep(i,65536) a[i]=a3[i]*a2[i];
    fwt(a,65535,0);

}
ll s[1000000];
ll dowork(int blo) {
    ll ans=0;
    for(int i=1;i<=n;i+=blo) {
        for(int j=i;j<=min(i+blo-1,n);j++) {
            Fork(l,i,j-1) 
                Fork(k,i,l-1) if ((a[k]^a[l])/2==a[j]) ++ans;
        }
    }
    MEM(s)
    for(int i=1;i<=n;i+=blo) {
        for(int j=i;j<=min(i+blo-1,n);j++) {
            Fork(l,i,j-1) ans+=s[(a[j]*2)^a[l]]+s[(a[j]*2+1)^a[l]];
        }
        for(int j=i;j<=min(i+blo-1,n);j++) {
            s[a[j]]++;
        }
    }
    for(int i=1;i<=n;i+=blo) {
        MEM(s)
        For(l,i-1) s[a[l]]++;
        work(s);
        s[0]-=i-1;
        for(int j=i;j<=min(i+blo-1,n);j++) {
            ans+=s[a[j]]/2;
        }
    }
    return ans;
}
void dowork2(int blo,ll &ans) {
    MEM(s)
    For(i,n) s[a[i]]++;
    work2(s);
    ans+=s[0];

}
void work_ik(ll &ans) {
    ll p1=0,p2,p3=0;
    MEM(s)
    For(i,n) s[a[i]]++;
    p1=s[0];
    p2=s[0]*n;
    For(i,n) {
        int l1=(2*a[i])^a[i],l2=(2*a[i]+1)^a[i];
        p3+=s[l1]+s[l2];
    }
    ll p4=p3;
    //p1 i=j=k;
    ans+=-p2-p3-p4+2*p1;
}
int main()
{
    freopen("F.in.cpp","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        n=read();
        For(i,n) a[i]=read();
        int blo=sqrt(n);

        ll ans=0;
        dowork2(blo,ans);
        work_ik(ans);
        ans-=dowork(blo)*2;
        For(i,n/2) swap(a[i],a[n-i+1]);
        ans-=dowork(blo)*2;
        ans/=2;     
        printf("%lld\n",ans);
    }
    return 0;
}

版本2(有序分4种情况):

#include<bits/stdc++.h>
using namespace std;
#define Rep(i,n) for(int i=0;i<n;i++)
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define pb push_back
#define MEM(f) memset(f,0,sizeof(f));
#define MAXN (523456+10)    
#define LL long long
int T;
int n,a[MAXN];
int read() {
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
#define N (65535)
typedef long long ll;
void fwt(LL a[],int n,bool on){
    for(int d=1;d<n;d<<=1){
        for(int k=d<<1,i=0;i<n;i+=k){
            for(int j=0;j<d;j++){
                LL x=a[i+j],y=a[i+j+d];
                if(on){
                    a[i+j]=(x+y);
                    a[i+j+d]=(x-y);
                }
                else{
                    a[i+j]=(x+y)/2;
                    a[i+j+d]=(x-y)/2;
                }
            }
        }
    }
}
ll a1[70000],a2[70000],a3[70000];
void work(ll a[],ll a2[]) {
    fwt(a,65535,1);
    fwt(a2,65535,1);
    Rep(i,65536) a[i]=a[i]*a2[i];
    fwt(a,65535,0);
    Rep(i,65536) a2[i]=0;
    Rep(i,65536) a2[i/2]+=a[i];
    Rep(i,65536) a[i]=a2[i];
}
ll dowork() {
    int blo=sqrt(n);
    ll ans=0;
    for(int i=1;i<=n;i+=blo) {
        for(int j=i;j<=min(i+blo-1,n);j++) {
            Fork(l,i,j-1) 
                Fork(k,i,l-1) if ((a[k]^a[j])/2==a[l]) ++ans;
        }
    }
    MEM(a1)
    for(int i=1;i<=n;i+=blo) {
        for(int j=i;j<=min(i+blo-1,n);j++) {
            Fork(l,i,j-1) {
                int p1=(a[l]*2)^a[j],p2=(a[l]*2+1)^a[j];
                if (p1>65535) p1=65546;
                if (p2>65535) p2=65546;
                ans+=a1[p1]+a1[p2]; 
            }
        }
        for(int j=i;j<=min(i+blo-1,n);j++) {
            a1[a[j]]++;
        }
    }

    MEM(a1)
    for(int i=(n-1)/blo*blo+1;i>=0;i-=blo) {
        for(int j=i;j<=min(i+blo-1,n);j++) {
            Fork(l,i,j-1) {
                int p1=(a[j]*2)^a[l],p2=(a[j]*2+1)^a[l];
                if (p1>65535) p1=65546;
                if (p2>65535) p2=65546;
                ans+=a1[p1]+a1[p2]; 
            }
        }
        for(int j=i;j<=min(i+blo-1,n);j++) {
            a1[a[j]]++;
        }
    }

    for(int i=1;i<=n;i+=blo) {
        MEM(a1) MEM(a2)
        For(j,i-1) a1[a[j]]++;
        Fork(j,i+blo,n) a2[a[j]]++;
        work(a1,a2);
        for(int j=i;j<=min(i+blo-1,n);j++) {
            ans+=a1[a[j]];
        }
    }
    return ans;
}
int main()
{
//  freopen("F.in.cpp","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        n=read();
        For(i,n) a[i]=read();

        ll ans=0;
        ans=dowork();
        printf("%lld\n",ans);
    }
    return 0;
}

G K-partite Graph

发布时间: 2017年4月19日 15:18 最后更新: 2017年4月19日 15:40 时间限制: 1000ms 内存限制: 128M

描述
We are all familiar wi
th bipartite graph, actually it can be extended to multipartite graph.

If vertices of an undirected graph G can be divided into exactly k(k≥2) non-empty sets, and for each pair of vertices u and v, there exists an edge (u, v) if and only if they are from different sets, then G is defined as a complete k-partite graph.

Given an undirected graph G with n vertices and m edges, judge whether it is a complete k-partite graph.

输入
The first line contains an integer number T, the number of test cases.

For each test case :

The first line contains two integers n and m(1≤n≤1000,0≤m≤n×(n−1)2), the number of vertices and edges.

i-th of each next m lines contains two integers ui ans vi, which means there exists an undirected edge between ui and vi (1≤ui,vi≤n,ui≠vi).

It’s also guaranteed that no duplicated edges in the input.

输出
For each test case :

print a number k if G is a complete k-partite graph(k≥2), print “0”(without quotation) otherwise.

#include<bits/stdc++.h>
using namespace std;
#define Rep(i,n) for(int i=0;i<n;i++)
#define For(i,n) for(int i=1;i<=n;i++)
#define pb push_back
#define F (1000000007)
#define MAXN (1011)
#define MEM(x) memset(x,0,sizeof(x));
int T;
int n,m;
int f[MAXN][MAXN];
int fa[MAXN];
int getfa(int x) {
    if (fa[x]==x) return x;
    return fa[x]=getfa(fa[x]);
}
void uni(int x,int y) {
    x=getfa(x);y=getfa(y);
    if (x!=y) fa[x]=y;
}
int check() {
    For(i,n) getfa(i);
    For(i,n) For(j,i-1)  {
        if (f[i][j] &&fa[i]==fa[j]) return 0;
        if (!f[i][j] &&fa[i]!=fa[j]) return 0;
    }
    int p=0;
    For(i,n) if (fa[i]==i) p++;
    if (p<2) p=0;
    return p;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);MEM(f)
        For(i,n) fa[i]=i;
        For(i,m) {
            int a,b;
            scanf("%d%d",&a,&b);
            f[a][b]=f[b][a]=1;
        }
        For(i,n) For(j,i-1 ) if (!f[i][j]) {
            uni(i,j);
        }
        printf("%d\n",check());
    }
    return 0;
}

H Boxes

发布时间: 2017年4月19日 15:19 最后更新: 2017年4月19日 15:41 时间限制: 3000ms 内存限制: 128M

描述
OldWC is a warehouseman, the warehouse can be described as a n×m grid, there are several(maybe none) boxes on each grid.In order to prevent dumping, on each grid, boxes can not be stacked for more than h layers.OldWC needs to move some boxes to meet the requirement, every time, he can move a box from one grid to an adjacent grid,two grids are adjacent if and only if they share an edge.

Calculate how many times he needs to move at least to make each pile of boxes within h layers.

输入
The first line contains an integer number T, the number of test cases.

For each test case :

The first line contains three integers n, m, h(1≤n,m,h≤50), the size of the warehouse and the limited number of layers.

The following n lines, each contains m integers aij(0≤aij≤50), the initial number of boxes on the ith row jth column.

It’s guaranteed that ∑aij≤n×m×h.

输出
For each test case print the answer.

#include<bits/stdc++.h>
using namespace std;

#define MAXN 50001
#define LL long long
struct Edge
{
    int t,w,next;
    LL c;
    Edge(int t=0,int w=0,int next=0,LL c=0):t(t),w(w),next(next),c(c){}
}e[1000001];
int head[MAXN];
LL d[MAXN];
bool used[MAXN];
int cnt,src,dst,cur;
void init(int n)
{
    cur=0;cnt=n;
    memset(head+1,-1,sizeof(int)*n);
}
void addEdge(int s,int t,int w,LL c)
{
    e[cur]=Edge(t,w,head[s],c);
    head[s]=cur++;
    e[cur]=Edge(s,0,head[t],-c);
    head[t]=cur++;
}
bool dijkstra()
{
    static pair<LL,int> q[MAXN];
    memset(d,0x3f,sizeof(LL)*(cnt+1));
    memset(used+1,0,sizeof(bool)*cnt);
    d[dst]=0;q[0]=make_pair(0,dst);
    for(int pos=1;pos;)
    {
        int i=q->second;
        pop_heap(q,q+pos--);
        if(used[i])continue;
        used[i]=true;
        for(int j=head[i];j!=-1;j=e[j].next)
        {
            int t=e[j].t;
            if(e[j^1].w && d[t] > d[i]-e[j].c)
            {
                d[t]=d[i]-e[j].c;
                q[pos++]=make_pair(-d[t],t);
                push_heap(q,q+pos);
            }
        }
    }
    return d[src]<d[0];
}
int dfs(int i,int flow)
{
    if(i==dst)return flow;
    used[i]=true;
    int ret=0;
    for(int j=head[i];j!=-1;j=e[j].next)
    {
        if(!e[j].c && e[j].w && !used[e[j].t])
        {
            int w=dfs(e[j].t,min(flow-ret,e[j].w));
            e[j].w-=w;e[j^1].w+=w;ret+=w;
            if(ret==flow)break;
        }
    }
    if(ret)used[i]=false;
    return ret;
}
LL costFlow()
{
    LL ret=0,dis=0;
    while(dijkstra())
    {
        for(int i=1;i<=cnt;i++)
        {
            for(int j=head[i];j!=-1;j=e[j].next)
                e[j].c+=d[e[j].t]-d[i];
        }
        dis+=d[src];
        memset(used+1,0,sizeof(bool)*cnt);
        ret+=dis*dfs(src,0x7fffffff);
    }
    return ret;
}
int main()
{
    int tt;
    scanf("%d",&tt);
    while(tt--){
        int n,m,h,t;
        scanf("%d%d%d",&n,&m,&h);
        init(n*m+2);src=n*m+1;dst=n*m+2;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%d",&t);
                addEdge(src,i*m+j+1,t,0);
                addEdge(i*m+j+1,dst,h,0);
                if(i)addEdge(i*m+j+1,(i-1)*m+j+1,0x7fffffff,1);
                if(j)addEdge(i*m+j+1,i*m+j,0x7fffffff,1);
                if(i!=n-1)addEdge(i*m+j+1,(i+1)*m+j+1,0x7fffffff,1);
                if(j!=n-1)addEdge(i*m+j+1,i*m+j+2,0x7fffffff,1);
            }
        }
        printf("%lld\n",costFlow());
    }
}

I Annual Party

描述
There are n cities in the Rainbow Island, connected by n−1 bidirectional roads. In the ith of each next m years, ki of the cities would like to hold a party and they would choose one from these ki cities as the place for the party. For convenience, every year, the sum of distance from the chosen city to all of these ki cities should be minimized.

Now you are given the map of the Rainbow Island and the ki cities which would hold the party, calculate the minimized sum of distance from the chosen city to all of the ki cities every year.

输入
The first line contains an integer number T, the number of test cases.

For each test case :

The first line contains two integers n, m(1≤n,m≤100000), number of cities and years.

The following n−1 lines, each contains three integers u,v,w(1≤u,v≤n, u≠v, 1≤w≤109), which means there is a bidirectional road between u and v, the length of road is w.

It’s guaranteed that the graph is connected.

i-th of each next m lines contains ki+1 integers, first is the number of cities for the party ki(1≤ki≤n), then come ki different integers a1, a2, … , aki(1≤aj≤n, 1≤j≤ki), the indexes of these ki cities.

It’s also guaranteed that for each test case ∑ki≤100000.

输出
For every year print the answer.

虚树

J Repeated String

描述
qwb has talent for solving string problems.He obtains a lowercase string A of length n×m, and he wants to construct another lowercase string B of the same length to make the distance from A to B as small as possible.Because of his laziness, he decides to construct B in an easy way. Firstly, he constructs a string of length n, then he repeats it for m times.

For two strings A and B with the same length L, their distance is defined as the following:

dist(A,B)=∑i=1L|A[i]−B[i]|
Tell qwb what’s the minimum distance he can get.

输入
The first line contains an integer number T, the number of test cases.

For each test case :

The first line contains two integers n, m(1≤n×m≤105).

The next line contains a lowercase string A of length n×m.

输出
For each test case print the minimum distance.

样例输入1 复制

#include<bits/stdc++.h>
using namespace std;
#define Rep(i,n) for(int i=0;i<n;i++)
#define For(i,n) for(int i=1;i<=n;i++)
#define pb push_back
int T;
int n,m,ans;
char s[123456];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        scanf("%s",s+1);
        ans=0;
        For(i,n) {
            vector<int> v;
            for(int j=i;j<=n*m;j+=n) {
                v.pb(s[j]);
            }
            sort(v.begin(),v.end());
            int sz=v.size();
            int p=sz/2;
            int c=0;
            Rep(i,sz) c+=max(v[p]-v[i],v[i]-v[p]);
            ans+=c;
        }

        printf("%d\n",ans);
    }
    return 0;
}

K Brackets

描述
Let us define a regular brackets sequence in the following way:

1.Empty sequence is a regular sequence.

2.If “S” is a regular sequence, then “(S)” is a regular sequence.

3.If “A” and “B” are regular sequences, then “AB” is a regular sequence.

For example, all of the following sequences are regular brackets sequences: “()”, “(())”, “()()”, “()(())”.

And all of the following sequences are not: “(”, “)”, “)(”, “((()”.

Doc has n pairs of brackets and he wants to know how many regular brackets sequences of length 2n can he construct that satisfy the x-th left bracket must not be matched before the y-th left bracket is matched(x<y), tell him the answer modulo 109+7.

输入
The first line contains an integer number T(T≤200), the number of test cases.

i-th of each next T lines contains three numbers n, x, y(2≤n≤500, 1≤x

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
LL f[1005][2][505];
LL ck[555],dp[555][555];
LL ss[555][555];
int T,n,x,y;

void add(LL &x,LL y){x=(x+y)%mod;}
void sub(LL &x,LL y){x=(x-y+mod)%mod;}

int main()
{
    f[0][0][0]=1;
    f[1][0][1]=1;
    for(int i=2;i<=1000;i++)
    {
        for(int k=1;k<=500;k++)
        {
            add(f[i][0][k],f[i-1][0][k-1]);
            add(f[i][0][k],f[i-1][1][k-1]);
        }
        for(int k=0;k<=499;k++)
        {
            add(f[i][1][k],f[i-1][0][k+1]);
            add(f[i][1][k],f[i-1][1][k+1]);
        }
    }
    ck[1]=1;ck[0]=1;
    for(int i=2;i<=500;i++)
    {
        for(int j=0;j<=i-1;j++)
            add(ck[i],ck[j]*ck[i-j-1]%mod);
    }
    for(int i=0;i<=501;i++)dp[0][i]=1;
    for(int n=1;n<=501;n++)
        for(int k=1;k<=501;k++)
            for(int i=0;i<=n;i++)
                add(dp[n][k],dp[n-i][k-1]*ck[i]%mod);
    for(int i=0;i<=501;i++)
    {
        ss[i][1]=dp[i][1];
        for(int j=2;j<=501;j++)
            add(ss[i][j],ss[i][j-1]+dp[i][j]);
    }
    scanf("%d",&T);
    while(T--)
    {
        LL ans=0;
        scanf("%d%d%d",&n,&x,&y);
        /*if(x==1)
        {
            for(int i=y-1;i<=n-1;i++)
                add(ans,ck[i]*dp[n-1-i][2]);
        }*/
        for(int i=0;i<=x-1;i++)
        {
            LL now=f[2*(x-1)-i][0][i];
            for(int j=y-x;j<=n-x;j++)
            {
                LL temp=now*ck[j]%mod;
                add(ans,temp*ss[n-x-j][i+1]);
                /*for(int k=1;k<=i+1;k++)
                    add(ans,(now*ck[j])%mod*dp[n-x-j][i+2-k]%mod);
                    */
            }
        }
        printf("%lld\n",ans);
    }
}

L QAQ Number

描述
QAQ, the greatest mathematician of the 21st century, found a new number called QAQ Number. The QAQ Numbers are positive integers without leading zeros which satisfy the following conditions:

1.It has exactly 3k digits(k is a positive integer), and can be divided into three sections a1...ak, ak+1...a2k and a2k+1...a3k.

2.Digits of the same section are the same. Explicitly, a1=a2=...=ak−1=ak, ak+1=ak+2=...=a2k−1=a2k, a2k+1=a2k+2=...=a3k−1=a3k.

3.The first and third sections are the same, which means a1=a2k+1, a2=a2k+2 , ... , ak=a3k.

For instance, 111222111, 919 and 666666 are QAQ Numbers, but 1111, 010 , 444455554443 are not.

Now QAQ wants to know how many QAQ Numbers are there in range [L, R](inclusive).

输入
The first line contains an integer number T, the number of test cases.

i-th of each next T lines contains two numbers L and R (1≤L≤R≤1018).

输出
For each test case print one number.

#include<cstdio>
#include<algorithm>
#include<string>
#include<string.h>
#include<cmath>
using namespace std;
long long s[100000];
int num;
void init()
{
    long long box[20];
    box[0]=1;
    for(int i=1;i<=18;i++)box[i]=box[i-1]*10;
    for(int i=1;i<=9;i++){
        for(int j=0;j<=9;j++){
            for(int k=1;k<=6;k++){
                long long t=0;
                for(int l=0;l<k;l++){
                    t+=i*box[l]+i*box[l+2*k]+j*box[l+k];
                }
                s[num++]=t;
            }
        }
    }
    sort(s,s+num);
}
int main()
{
    init();
    int tt;
    scanf("%d",&tt);
    while(tt--){
        long long l,r,ans1,ans2;
        scanf("%lld%lld",&l,&r);
        ans1=upper_bound(s,s+num,l-1)-s;
        ans2=upper_bound(s,s+num,r)-s;
        printf("%lld\n",ans2-ans1);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值