ACM训练联盟周赛(第三场)

A.Teemo's bad day

Today is a bad day. Teemo is scolded badly by his teacher because he didn't do his homework.But Teemo is very self-confident, he tells the teacher that the problems in the homework are too simple to solve. So the teacher gets much angrier and says"I will choose a problem in the homework, if you can't solve it, I will call you mother! "java

The problem is that:node

There is an array A which contains n integers, and an array B which also contains n integers. You can pay one dollar to buy a card which contains two integers a1 and a2, The card can arbitrary number of times transform a single integer a1 to a2 and vise-versa on both array A and Array B. Please calculate the minimum dollars you should pay to make the two array same(For every 1<=i<=n,A[i]=B[i]);ios

Input Formatc++

  • The first line of the input contains an integer T(1<=T<=10), giving the number of test cases.
  • For every test case, the first line contains an integer n(1<=n<=500000). The second line contains n integers. The i th integer represents A[i](1<=A[i]<=100000). And the third line contains n integers. The i th integer represents B[i](1<=B[i]<=100000).

Output Formatapp

For each test case, output an integer which means the minimum dollars you should pay in a line.eclipse

样例输入

1
5
1 1 2 3 2
1 2 3 1 1

样例输出

2
将不匹配的联通跑bfs就能够
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#pragma GCC diagnostic error "-std=c++11"
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define esp 1e-9
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 0x3f3f3f3f
#define mem(a) (memset(a,0,sizeof(a)))
int dcmp(double x){return fabs(x)<esp?0:x<0?-1:1;}
typedef long long ll;
int t,n,a[500005],b[500005];
int vis[100005],c[100005];
vector<int>v[100005];
void dfs(int u){
    vis[u]=1;
    for(auto t:v[u]){
        if(!vis[t]) dfs(t);
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        memset(c,0,sizeof(c));
        scanf("%d",&n);
        for(int i=0;i<=100001;i++)
            v[i].clear();
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        for(int i=0;i<n;i++){
            scanf("%d",&b[i]);
            if(a[i]==b[i]) continue;
            c[a[i]]=1;
            c[b[i]]=1;
            v[a[i]].push_back(b[i]);
            v[b[i]].push_back(a[i]);
        }
        int ans=0,pos=0;
        for(int i=1;i<=100000;i++)
        {
            if(c[i]){
                pos++;
                if(!vis[i]){
                    dfs(i);
                    ans++;
                }
            }
        }
        printf("%d\n",pos-ans);
    }
    return 0;
}

 

B.Teemo's hard problem

Teemo starts to do homework everyday. Today, he meets a hard problem when doing his homework.ide

There's an array A which contains n integers(for every 1<=i<=n, A[i] = 1 or A[i]= 2), you can choose an interval [l,r](1<=l<=r<=n), then reverse it so that the length of the longest non-decreasing subsequence of the new sequence is maximum.ui

Input Formatthis

  • The first line of the input contains an integer T(1=<T<=10), giving the number of test cases.
  • For every test case, the first line contains an integer n(1<=n<=2000). The second line contains n integers. The i th integer represents A[i](1<=A[i]<=2). 

Output Formatspa

Print a single integer, which means the maximum possible length of the longest non-decreasing subsequence of the new sequence.

样例输入

1
4
1 2 1 2

样例输出

4
暴力求出正反最长上升子序列,枚举区间
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#pragma GCC diagnostic error "-std=c++11"
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define esp 1e-9
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 0x3f3f3f3f
#define mem(a) (memset(a,0,sizeof(a)))
int dcmp(double x){return fabs(x)<esp?0:x<0?-1:1;}
typedef long long ll;
int t,n,a[2006];
int dpf[2006][2006],dpl[2006][2006];
int b[2006],ans,pos;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        memset(dpf,0,sizeof(dpf));
        memset(dpl,0,sizeof(dpl));
        for(int i=1;i<=n;i++)
        {
            pos=0;
            memset(b,0,sizeof(b));
            for(int j=i;j<=n;j++)
            {
                if(a[j]>=b[pos]) b[++pos]=a[j];
                else
                {
                    int k=upper_bound(b+1,b+pos+1,a[j])-b;
                    b[k]=a[j];
                }
                dpf[i][j]=pos;
            }
        }
        for(int i=n;i;i--)
        {
            pos=0;
            memset(b,0,sizeof(b));
            for(int j=i;j;j--)
            {
                if(a[j]>=b[pos]) b[++pos]=a[j];
                else
                {
                    int k=upper_bound(b+1,b+pos+1,a[j])-b;
                    b[k]=a[j];
                }
                dpl[j][i]=pos;
            }
        }
        ans=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                ans=max(ans,dpf[1][n]-dpf[i][j]+dpl[i][j]);
        printf("%d\n",ans);
    }
    return 0;
}

 



C.Teemo's tree problem

There is an apple tree in Teemo's yard. It contains n nodes and n-1 branches, and the node 1 is always the root of the tree. Today, Teemo's father will go out for work. So Teemo should do his father's job in the family: Cut some branches to make the tree more beautiful. His father's told him that he should cut some branches, finally, the tree should just contains q branches. But when Teemo start to cut, he realizes that there are some apples in the branches( For example, there are 10 apples in the branches which connecting node 1 and node 4). So Teemo not only wants to achieve his father's order, but also wants to preserve apples as much as possible. Can you help him?

 
1
2   5
2
 \ / 
3
  3   4
4
   \ /
5
    1

Input Format

  • The first line of the input contains an integer T(1<=T<=10) which means the number of test cases.
  • For each test case, The first line of the input contains two integers n,q(3<=n<=100,1<=q<=n-1), giving the number of the node and the number of branches that the tree should preserve.
  • In the next n-1 line, each line contains three integers u,v,w(1<=u<=n,1<=v<=n,u!=v,1<=w<=100000), which means there is a branch connecting node u and node v, and there are w apple(s) on it.

Output Format

Print a single integer, which means the maximum possible number of apples can be preserved.

样例输入

1
5 2
1 3 1
1 4 10
2 3 20
3 5 20

样例输出

21
树型DP,只有n-1边,一遍dfs,把边的权值赋给子节点,1结点赋成无限大
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <ext/rope>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#pragma GCC diagnostic error "-std=c++11"
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define esp 1e-9
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 1044266560
#define mem(a) (memset(a,0,sizeof(a)))
int dcmp(double x){return fabs(x)<esp?0:x<0?-1:1;}
typedef long long ll;
typedef pair<int,int> P;
int n,m,t,f[106][106];
int vis[106],val[106],ans;
vector<P>v[106];
void solve(int u)
{
    vis[u]=1;
    for(int i=0;i<v[u].size();i++)
    {
        if(!vis[v[u][i].first]){
            val[v[u][i].first]=v[u][i].second;
            solve(v[u][i].first);
        }
    }
}
int dfs(int u,int fa)
{
    vis[u]=1;
    for(int i=0;i<v[u].size();i++)
    {
        if(v[u][i].first==fa) continue;
        vis[u]+=dfs(v[u][i].first,u);
    }
    f[u][1]=val[u];
    for(int i=0;i<v[u].size();i++){
        if(v[u][i].first==fa) continue;
        for(int j=vis[u];j>=1;j--){
            for(int k=0;k<j && k<=vis[v[u][i].first];k++)
                f[u][j]=max(f[u][j],f[u][j-k]+f[v[u][i].first][k]);
        }
    }
    if(vis[u]>=m) ans=max(ans,f[u][m]);
    return vis[u];
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        memset(vis,0,sizeof(vis));
        memset(val,0,sizeof(val));
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++)
            v[i].clear();
        for(int i=1,x,y,z;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            v[x].push_back(P(y,z));
            v[y].push_back(P(x,z));
        }
        solve(1);
        memset(vis,0,sizeof(vis));
        val[1]=1000000;
        m++;
        ans=-1;
        dfs(1,0);
        printf("%d\n",ans-val[1]);
    }
    return 0;
}

 

F.Teemo's dream

Teemo decides to use his money to conquer the universe.

It is known that there are m planets that humans can reach at present. They are numbered from 1 to m. Teemo bought n kinds of gateways. Their IDs are a1, a2, ..., an, the gateway whose ID is ai can transmit Teemo to the stars numbered ai,2ai, 3ai, ..., k*ai (1<=k*ai<=m, k is a positive integer), now Teemo wants to know, how many planets can he reach?

 

Input Format

On the firstline one positive number: the number of test cases, at most 20. After that per test case:

  • One line contains two integers n and m, (1 <= n <= 15, 1<= m < = 1e9), respectively represent the number of the gateway, the number of the stars that humans can reach.
  • One line contains integers, the i-th integer a[i], indicating that the ID of the  i-th gateway is a[i], (2<=a[i]<=1e9).

 

Ouput Format

Per test case:

  • One line contains an integer, which indicates how many planets Teemo can reach at most.

容斥定理

1到m包含多少个a[i]的倍数

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#pragma GCC diagnostic error "-std=c++11"
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define esp 1e-9
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 0x3f3f3f3f
#define mem(a) (memset(a,0,sizeof(a)))
int dcmp(double x){return fabs(x)<esp?0:x<0?-1:1;}
typedef long long ll;
ll t,n,m;
ll a[16],b[16],ans=0;
ll lcm(ll x,ll y){
    return x/__gcd(x,y)*y;
}
void solve(int n,int l,int r,int k)
{
    for(int i=n;i>=l;i--)
    {
        b[l-1]=a[i-1];
        if(l>1) solve(i-1,l-1,r,k);
        else{
            ll pos=lcm(b[r-1],b[r-2]);
            for(int j=r-3;j>=0;j--)
            {
                pos=lcm(pos,b[j]);
                if(pos>m) goto eg;
            }
            if(k) ans+=m/pos;
            else ans-=m/pos;
            eg:;
        }
    }
}
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&m);
        ans=0;
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&a[i]);
            ans+=m/a[i];
        }
        for(int i=2;i<=n;i++)
            solve(n,i,i,i&1);
        printf("%lld\n",ans);
    }
    return 0;
}

 

G.Teemo's convex polygon

Teemo is very interested in convex polygon. There is a convex n-sides polygon, and Teemo connect every two points as diagonal lines, and he want to kown how many segments which be divided into intersections. Teemo ensure that any three diagonals do not intersect at a point.

As the result may be very large, please output the result mod 1000000007.

Input Format

The input contains several test cases, and the first line is a positive integer T indicating the number of test cases which is up to 100.

For each test case, the first line contains an integer n(3<=n<=10^18).

Output Format

For each test case, output a line containing an integer that indicates the answer.

样例输入

2
3
4

样例输出

0
4
数据保证没有三条线段交于一点,公式为(n^4-6n^3+17n^2-24n)/12
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
    static Scanner cin = new Scanner(System.in);
    static BigInteger[] a = new BigInteger[10];
    public static void  main(String args[]){
        long n,m;
        m = cin.nextLong();
        while(m>0){
            m =m-1;
            n = cin.nextLong();
            a[1] = BigInteger.valueOf(n);
            a[2] = a[1].multiply(BigInteger.valueOf(n));
            a[3] = a[2].multiply(BigInteger.valueOf(n));
            a[4] = a[3].multiply(BigInteger.valueOf(n));
            a[3] = a[3].multiply(BigInteger.valueOf(6));
            a[2] = a[2].multiply(BigInteger.valueOf(17));
            a[1] = a[1].multiply(BigInteger.valueOf(24));
            a[5] = a[4].subtract(a[3]);
            a[5] = a[5].add(a[2]);
            a[5] = a[5].subtract(a[1]);
            a[5] = a[5].divide(BigInteger.valueOf(12));
            System.out.println(a[5].mod(BigInteger.valueOf(1000000007)));
        }
    }
}

 

J.Teemo's formula

Teemo has a formula and he want to calculate it quickly.

The formula is .

As the result may be very large, please output the result mod 1000000007.

Input Format

The input contains several test cases, and the first line is a positive integer T indicating the number of test cases which is up to 10^5.

For each test case, the first line contains an integer n(1<=n<=10^9).

Output Format

For each test case, output a line containing an integer that indicates the answer.

样例输入

2
2
3

样例输出

6
24
组合公式n(n+1)2^(n-2)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <ext/rope>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#pragma GCC diagnostic error "-std=c++11"
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define esp 1e-9
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 1044266560
#define mem(a) (memset(a,0,sizeof(a)))
int dcmp(double x){return fabs(x)<esp?0:x<0?-1:1;}
typedef long long ll;
ll n,t; 
ll quick_pow(ll x,ll y)
{
    ll ans=1;
    while(y){
        if(y&1) ans=ans*x%MOD;
        y>>=1;
        x=x*x%MOD;
    }
    return ans;
}
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld",&n);
        if(n==1) {printf("1\n");continue;}
        printf("%lld\n",n*(n+1)%MOD*quick_pow(2,n-2)%MOD);
    }
    return 0;
}

 

K.Teemo's reunited

Teemo likes to drink raspberry juice.  He even spent some of his spare time tomake the raspberry juice himself. The way to make the raspberries juice is simple. You just have to press the raspberries through a fine sieve.

Unfortunately,today Teemo was splited in several pieces by the sieve which was used to makethe raspberry juice. The pieces were losted in the huge two-dimensional map. Onlywhen all the pieces gather, can Teemo drink the raspberry juice he made today. 

Teemo's piece can only move parallel to the x or y axis, or he would be hated by theraspberry Queen and will not be able to have raspberry juice any more. One of the piece of Teemo should carry the raspberry juice.In order to avoid spilling, this piece cannot move anymore. 

Teemo’spiece are lazy, they’d like to make the sum of paths be the minimal. Your task is to find the minimal sum of the paths.

InputFormat
The first line contains a integer n (1<=n<=100000) represent the number of thepieces. Then next n lines. Each line contains the pairs of xi, yi(-1000000000<xi,yi<1000000000) in turn as points by order.

OutputFormat
Printa single line contains the minimal sum of the paths.

样例输入1

3
1 0
2 0
3 0

样例输出1

2

样例输入2

5
4 1
4 4
9 2
2 9
2 6

样例输出2

21
在这些点中找一个点使得全部的点到此点的曼哈顿距离最小,分别对x,y排序
枚举x,y找出不一样的x,y对应的最小值,最后枚举点使得x+y最小
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#pragma GCC diagnostic error "-std=c++11"
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define esp 1e-9
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 0x3f3f3f3f
#define mem(a) (memset(a,0,sizeof(a)))
int dcmp(double x){return fabs(x)<esp?0:x<0?-1:1;}
typedef long long ll;
const int lower=1000000000;
struct Point
{
    ll x,y,num;
}e[200005];
ll sum_x[200005],sum_y[200005],n,sumx=0,sumy=0;
ll l[200005],r[200005];
bool cmpx(const Point &a,const Point &b){return a.x<b.x;}
bool cmpy(const Point &a,const Point &b){return a.y<b.y;}
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&e[i].x,&e[i].y);
        e[i].x+=lower;
        e[i].y+=lower;
        e[i].num=i;
        sumx+=e[i].x;
        sumy+=e[i].y;
    }
    sort(e+1,e+1+n,cmpx);
    for(int i=1;i<=n;i++)
        sum_x[i]=sum_x[i-1]+e[i].x;
    for(int i=1;i<=n;i++)
    {
        ll x=e[i].x;
        ll left=(i-1)*x-sum_x[i-1];
        ll right=sumx-sum_x[i]-(n-i)*x;
        l[e[i].num]=left+right;
    }
    sort(e+1,e+1+n,cmpy);
    for(int i=1;i<=n;i++)
        sum_y[i]=sum_y[i-1]+e[i].y;
    for(int i=1;i<=n;i++)
    {
        ll y=e[i].y;
        ll left=(i-1)*y-sum_y[i-1];
        ll right=sumy-sum_y[i]-(n-i)*y;
        r[e[i].num]=left+right;
    }
    ll inf=l[1]+r[1];
    for(int i=2;i<=n;i++)
        inf=min(inf,l[i]+r[i]);
    printf("%lld\n",inf);
    return 0;
}