Codeforces514

这次考试题目顺序换过了,萎了,QAQ
Luke Skywalker gave Chewbacca an integer number x. Chewbacca isn’t good at numbers but he loves inverting digits in them. Inverting digit t means replacing it with digit 9 - t.

Help Chewbacca to transform the initial number x to the minimum possible positive number by inverting some (possibly, zero) digits. The decimal representation of the final number shouldn’t start with a zero.

Input
The first line contains a single integer x (1 ≤ x ≤ 1018) — the number that Luke Skywalker gave to Chewbacca.

Output
Print the minimum possible positive number that Chewbacca can obtain after inverting some digits. The number shouldn’t contain leading zeroes.

Example
Input
27
Output
22
Input
4545
Output
4444

本题水题,读入之后首位为9特判一下,其他情况就是一位位比较过去

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 19
int a[101];
char xx[101];
int len;
char c=1;
int main()
{
    len=0;
    while(!isdigit(c))
    {
        c=getchar();
    }
    while(isdigit(c))
    {
        a[++len]=c-'0';
        c=getchar();
    }
    for(int i=1;i<=len;i++)
    {
        if(i==1&&a[i]==9) continue;
        if(a[i]>4) a[i]=9-a[i];
    }
    for(int i=1;i<=len;i++) cout<<a[i];
}

**There are n Imperial stormtroopers on the field. The battle field is a plane with Cartesian coordinate system. Each stormtrooper is associated with his coordinates (x, y) on this plane.

Han Solo has the newest duplex lazer gun to fight these stormtroopers. It is situated at the point (x0, y0). In one shot it can can destroy all the stormtroopers, situated on some line that crosses point (x0, y0).

Your task is to determine what minimum number of shots Han Solo needs to defeat all the stormtroopers.

The gun is the newest invention, it shoots very quickly and even after a very large number of shots the stormtroopers don’t have enough time to realize what’s happening and change their location.

Input
The first line contains three integers n, x0 и y0 (1 ≤ n ≤ 1000,  - 104 ≤ x0, y0 ≤ 104) — the number of stormtroopers on the battle field and the coordinates of your gun.

Next n lines contain two integers each xi, yi ( - 104 ≤ xi, yi ≤ 104) — the coordinates of the stormtroopers on the battlefield. It is guaranteed that no stormtrooper stands at the same point with the gun. Multiple stormtroopers can stand at the same point.

Output
Print a single integer — the minimum number of shots Han Solo needs to destroy all the stormtroopers.

Example
Input
4 0 0
1 1
2 2
2 0
-1 -1
Output
2
Input
2 1 2
1 1
1 0
Output
1**
这题就是顺序扫一遍,一只只鸟扫过来打,看误伤了哪些去掉就行了。
计算几何推一发

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<new>
#include<queue>
#include<stack>
#include<fstream>
#define N 1001
using namespace std;
int x0,y0;
int x[N],y[N];
int n;
bool vis[N];
int ans;
bool pan(int s1,int s2)
{
    int x1=x[s1],x2=x[s2],y1=y[s1],y2=y[s2];
    if((y2-y1)*(x0-x1)==(y0-y1)*(x2-x1)) return 1;
    return 0;
}
int main()
{
    cin>>n>>x0>>y0;
    for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
    for(int i=1;i<=n;i++)
    {
        if(vis[i]) continue;
        ans++;
        for(int j=i+1;j<=n;j++)
        {
            if(pan(i,j)) vis[j]=1;
        }
    }
    cout<<ans;
}

**Watto, the owner of a spare parts store, has recently got an order for the mechanism that can process strings in a certain way. Initially the memory of the mechanism is filled with n strings. Then the mechanism should be able to process queries of the following type: “Given string s, determine if the memory of the mechanism contains string t that consists of the same number of characters as s and differs from s in exactly one position”.

Watto has already compiled the mechanism, all that’s left is to write a program for it and check it on the data consisting of n initial lines and m queries. He decided to entrust this job to you.

Input
The first line contains two non-negative numbers n and m (0 ≤ n ≤ 3·105, 0 ≤ m ≤ 3·105) — the number of the initial strings and the number of queries, respectively.

Next follow n non-empty strings that are uploaded to the memory of the mechanism.

Next follow m non-empty strings that are the queries to the mechanism.

The total length of lines in the input doesn’t exceed 6·105. Each line consists only of letters ‘a’, ‘b’, ‘c’.

Output
For each query print on a single line “YES” (without the quotes), if the memory of the mechanism contains the required string, otherwise print “NO” (without the quotes).

Example
Input
2 3
aaaaa
acacaca
aabaa
ccacacc
caaac
Output
YES
NO
NO**

暴力跑trie树,我们理论证明了,这是不可能被卡掉的
为什么这时不会被卡掉的呢,证明比较玄学,我们知道输入最多也就30W个字符,而且字母就只有三种选择,首先我们考虑最卡的情况,此时所有trie树中的点都被遍历了1次,我们不妨将输入模板串和原串的字符各有60W,我们可以做到,让每次询问Trie树中所有节点都遍历1次,这个时候我们可以构造出一颗中间三叉两边挂链的树,我们设询问串和原串的长度均为x,是、则首先:我们不允许存在挂不下的情况。所以我们就考虑所有串都有点可挂。则可查询次数为60W/x,可遍历的节点的个数少于60W-x^2/2的,而且因为满足上述性质,所以(60W-x^2/2)

#include<bits/stdc++.h>
using namespace std;
#define N 100001
int xx[N];
int ans;
long long res=0;
int main()
{
    for(int x=1;x<=600000;x++)
    {
        long long i1=600000-(x*x)/2,i2=x*x;
        if(i1>i2)continue;
        long long hh=600000/x;
        long long it=hh*i1;
        if(it>res){res=it;ans=x;}
//      if(it<=0) break;
    }
    cout<<ans<<" "<<res;
}
%:pragma GCC optimize(4)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int son[700001][4];
int n,m,k;
char s[600001];
int sz;
int root;
int zhuan='a'-1;
bool dance[700001];
bool have[700001];
bool hack(int ll,int rr,int it)
{
    int p=it;
    for(int i=ll;i<=rr;i++)
    {
        if(son[p][s[i]-zhuan])
        p=son[p][s[i]-zhuan];else return 0;
    }
    if(dance[p]) return 1;
    return 0;
}
bool check()
{
    int len=strlen(s+1);
    //大于会RE 
    int p=root;
    if(!have[len]) return 0;
    for(int i=1;i<=len;i++)
    {
        for(int kk=1;kk<=3;kk++)
        {
            if(kk!=s[i]-zhuan&&son[p][kk])
            if(hack(i+1,len,son[p][kk])||(i==len&&dance[son[p][kk]]))
            return 1;
        }
        if(son[p][s[i]-zhuan])p=son[p][s[i]-zhuan];else return 0;
    }
    return 0;
}
int main()
{
    cin>>n>>m;
    root=++sz;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        int len=strlen(s+1);
        have[len]=1;
        int p=root;
        for(int j=1;j<=len;j++)
        {
            if(!son[p][s[j]-zhuan]) son[p][s[j]-zhuan]=++sz;
            p=son[p][s[j]-zhuan];
        }
        dance[p]=1;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s+1);
        if(check())
        {
            puts("YES");
        }
        else puts("NO");
    }
}

An army of n droids is lined up in one row. Each droid is described by m integers a1, a2, …, am, where ai is the number of details of the i-th type in this droid’s mechanism. R2-D2 wants to destroy the sequence of consecutive droids of maximum length. He has m weapons, the i-th weapon can affect all the droids in the army by destroying one detail of the i-th type (if the droid doesn’t have details of this type, nothing happens to it).

A droid is considered to be destroyed when all of its details are destroyed. R2-D2 can make at most k shots. How many shots from the weapon of what type should R2-D2 make to destroy the sequence of consecutive droids of maximum length?

Input
The first line contains three integers n, m, k (1 ≤ n ≤ 105, 1 ≤ m ≤ 5, 0 ≤ k ≤ 109) — the number of droids, the number of detail types and the number of available shots, respectively.

Next n lines follow describing the droids. Each line contains m integers a1, a2, …, am (0 ≤ ai ≤ 108), where ai is the number of details of the i-th type for the respective robot.

Output
Print m space-separated integers, where the i-th number is the number of shots from the weapon of the i-th type that the robot should make to destroy the subsequence of consecutive droids of the maximum length.

If there are multiple optimal solutions, print any of them.

It is not necessary to make exactly k shots, the number of shots can be less.

Example
Input
5 2 4
4 0
1 2
2 1
0 2
1 3
Output
2 2
Input
3 2 4
1 2
1 3
2 2
Output
1 3
Note
In the first test the second, third and fourth droids will be destroyed.

In the second test the first and second droids will be destroyed.
其实这道题两个指针狂扫即可,但我只想到了二分答案+线段树的做法所以就可以AC了,二分新姿势get!

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<new>
#include<queue>
using namespace std;
#define N 500001
#define M 8
int L[N],R[N],val[N][M],lazy[N][M],n,m,k;
int l,r;
bool flag=0;
int xx[M];
int a[N][M];
void build(int no,int l,int r)
{
    L[no]=l;R[no]=r;
    if(l==r) 
    {
        for(int i=1;i<=m;i++)
        val[no][i]=a[l][i];
        return;
    }
    int mid=(l+r)>>1;
    build(no*2,l,mid);
    build(no*2+1,mid+1,r);
    for(int i=1;i<=m;i++)
    {
        val[no][i]=max(val[no*2][i],val[no*2+1][i]);
    }
    return;
}
int query(int ty,int no,int l,int r)
{
    if(L[no]==l&&R[no]==r) return val[no][ty];
    int mid=(L[no]+R[no])>>1;
    if(l>mid) return query(ty,no*2+1,l,r);
    if(r<=mid) return query(ty,no*2,l,r);
    return max(query(ty,no*2,l,mid),query(ty,no*2+1,mid+1,r));
}
int ans[M];
bool pan(int x)
{
    if(x==0) return 1;
    for(int b=1;b<=n-x+1;b++)
    {
        memset(xx,0,sizeof(xx));
        int sum=0;
        for(int i=1;i<=m;i++)
        {
            xx[i]=query(i,1,b,b+x-1);
            sum+=xx[i];
        }
        if(sum<=k) 
        {
            for(int i=1;i<=m;i++)
            ans[i]=xx[i];
            return 1;
        }   
    }
    return 0;
}
void print()
{
    for(int i=1;i<=m;i++)cout<<ans[i]<<" ";
}
int main()
{
    cin>>n>>m>>k;
    l=0;r=n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        cin>>a[i][j];
    }
    build(1,1,n);
    while(l<=r)//要小于等于 
    {
        int mid=(l+r)>>1;
        if(pan(mid))
        {
            l=mid+1;
        }
        else r=mid-1;
    }
    print();
}

When Darth Vader gets bored, he sits down on the sofa, closes his eyes and thinks of an infinite rooted tree where each node has exactly n sons, at that for each node, the distance between it an its i-th left child equals to di. The Sith Lord loves counting the number of nodes in the tree that are at a distance at most x from the root. The distance is the sum of the lengths of edges on the path between nodes.

But he has got used to this activity and even grew bored of it. ‘Why does he do that, then?’ — you may ask. It’s just that he feels superior knowing that only he can solve this problem.

Do you want to challenge Darth Vader himself? Count the required number of nodes. As the answer can be rather large, find it modulo 109 + 7.

Input
The first line contains two space-separated integers n and x (1 ≤ n ≤ 105, 0 ≤ x ≤ 109) — the number of children of each node and the distance from the root within the range of which you need to count the nodes.

The next line contains n space-separated integers di (1 ≤ di ≤ 100) — the length of the edge that connects each node with its i-th child.

Output
Print a single number — the number of vertexes in the tree at distance from the root equal to at most x.

Example
Input
3 3
1 2 3
Output
8

本题是神奇的矩阵优化,先贴一发暴力,说明一下DP方法

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
using namespace std;
map<int,long long>M;
int n,x;
int a[100001];
#define r(x) scanf("%d",&x)
set<int>it;
int pg[101];
int sum;
long long mod=1e9+7;
long long dfs(int x)
{
    long long ans=1;
    if(x<=300000)
    if(M.count(x)) return M[x];
    if(x==0) return 1;
    for(int i=1;i<=100;i++)
    {
        if(pg[i]&&x>=i)
        ans+=(pg[i]*dfs(x-i))%mod;
        ans=ans%mod;
    }
    if(x<=300000)
    M[x]=ans;
    return ans;
}
int main()
{
    r(n);r(x);
    for(int i=1;i<=n;i++) r(a[i]);
    for(int i=1;i<=n;i++) pg[a[i]]++;
    cout<<dfs(x)%mod<<endl;
}

然后就是可以构造矩阵,这其实是类似一个模板,我们对于任何一维的需要前面状态有限的线性DP可以如下构造:
就是构造第一行放着一大堆系数,然后下面每条对角线放一,然后每乘一次就会滚动一次,然后我们有常数1,所以在最后一列上放上1在DP矩阵最后加一行1,就可以实现,矩阵快速幂优化DP

#include<cstdio>
#include<iostream>
using namespace std;
#define N 101
struct ret{
    long long xx[102][102];
}it,dancer,f[32];
int n,m;
int pg[101];
int x,y;
const long long mod=1e9+7;
#define r(x) scanf("%d",&x)
ret firedancer;
ret cheng(ret x,ret y)
{
    for(int i=1;i<=101;i++)
    for(int j=1;j<=101;j++)
    {
        long long t=0;
        for(int k=1;k<=101;k++)
        {
            t+=x.xx[i][k]*y.xx[k][j];
            t=t%mod;
        }
        firedancer.xx[i][j]=t;
    }
    return firedancer;
}
int main()
{
    r(n);r(m);
    for(int i=1;i<=n;i++)
    {
        r(y);pg[y]++;
    }
    dancer.xx[1][1]=1;dancer.xx[1][101]=1;
    for(int i=2;i<=100;i++) f[0].xx[i-1][i]=1;
    for(int i=1;i<=100;i++) f[0].xx[i][1]=pg[i];
    f[0].xx[101][1]=1;f[0].xx[101][101]=1;
    for(int i=1;i<=30;i++)
    {
        f[i]=cheng(f[i-1],f[i-1]);
    }
    int cnt=0;
    while(m)
    {
        if(m%2)
        dancer=cheng(dancer,f[cnt]);
        m>>=1;
        cnt++;
    }
    cout<<dancer.xx[1][1];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值