2016弱校联萌十一专场10.3 遗憾题合集

http://acm-icpc.aitea.net/index.php?2016%2FPractice%2F%E6%A8%A1%E6%93%AC%E5%9C%B0%E5%8C%BA%E4%BA%88%E9%81%B8%2F%E8%AC%9B%E8%A9%95

C.We don‘t wanna work!

@siludose 你要的代码,做好了参考看

SB模拟,xjb模拟

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <queue>
#include <bitset>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
const  int MAXN = 1e6+5;
struct Node
{
    string s;
    int time;
    int d;
} a[MAXN];
bool cmp(Node a, Node b)
{
    if(a.d == b.d)
        return a.time > b.time;
    return a.d > b.d;
}
struct cmp2
{
    bool operator()(const Node a, const Node b)const
    {
        if(a.d == b.d)
            return a.time > b.time;
        return a.d > b.d;
    }
};
struct cmp1
{
    bool operator()(const Node a, const Node b)const
    {
        if(a.d == b.d)
            return a.time < b.time;
        return a.d < b.d;
    }
};
set<Node,cmp1>se1;
set<Node,cmp2>se2;
map<string,Node>mp;
string s;
int main()
{
    int n, m;
    while(~scanf("%d",&n))
    {
        se1.clear();
        se2.clear();
        mp.clear();
        double tp = 1.0*n*0.2;
        int nn = (int)tp;
        int tn = n;
        for(int i=1; i<=tn; i++)
        {
            a[i].time = i;
            cin>>a[i].s>>a[i].d;
            mp[a[i].s] = a[i];
        }
        sort(a+1, a+1+tn, cmp);
        for(int i=1; i<=nn; i++)
            se1.insert(a[i]);
        for(int i=nn+1; i<=n; i++)
            se2.insert(a[i]);
        scanf("%d",&m);
        Node tmp;
        for(int i=tn+1; i<=tn+m; i++)
        {
            char op;
            cin>>op;
            if(op == ‘-‘)
            {
                cin>>s;
                tmp = mp[s];
                if(se1.erase(tmp)) nn--;
                se2.erase(tmp);
                if(nn>(int)(1.0*(n-1)*0.2))
                {
                    nn--;
                    tmp=*se1.begin();
                    se1.erase(tmp);
                    se2.insert(tmp);
                    cout<<tmp.s;
                    printf(" is not working now.\n");
                }
                n--;
                if(nn<(int)(1.0*(n)*0.2))
                {
                    nn++;
                    tmp=*se2.begin();
                    se1.insert(tmp);
                    se2.erase(tmp);
                    cout<<tmp.s;
                    printf(" is working hard now.\n");
                }
            }
            else///++
            {
                cin>>a[i].s>>a[i].d;
                a[i].time=i;
                mp[a[i].s]=a[i];
                //cout<<nn<<" "<<n<<endl;
                if(nn<(int)(1.0*(n+1)*0.2))///+0.2
                {
                    if(a[i].d>(*se2.begin()).d||a[i].d==(*se2.begin()).d&&a[i].time>(*se2.begin()).time)
                    {
                        se1.insert(a[i]);
                        cout<<a[i].s;
                        printf(" is working hard now.\n");
                    }
                    else
                    {
                        tmp=*se2.begin();
                        se2.erase(tmp);
                        se1.insert(tmp);
                        se2.insert(a[i]);
                        cout<<a[i].s;
                        printf(" is not working now.\n");
                        cout<<tmp.s;
                        printf(" is working hard now.\n");
                    }
                    nn++;
                    //cout<<"nn"<<nn<<endl;
                }
                else///=0.2
                {
                    if(nn!=0)
                    {
                        tmp=*se1.begin();
                        if(a[i].d>tmp.d||a[i].d==tmp.d&&a[i].time>tmp.time)
                        {
                            se1.erase(tmp);
                            se1.insert(a[i]);
                            se2.insert(tmp);
                            cout<<a[i].s;
                            printf(" is working hard now.\n");
                            cout<<tmp.s;
                            printf(" is not working now.\n");
                        }
                        else
                        {
                            se2.insert(a[i]);
                           // se2.erase(tmp);
                            //se1.insert(tmp);
                            cout<<a[i].s;
                            printf(" is not working now.\n");
                            //cout<<tmp.s;
                            //printf(" is working hard now.\n");
                            ///
                        }
                    }
                    else
                    {
                        tmp=*se2.begin();
                        if((int)(1.0*(n+1)*0.2)>0)
                        {
                            if(a[i].d>tmp.d||a[i].d==tmp.d&&a[i].time>tmp.time)
                            {
                                se1.insert(a[i]);
                                cout<<a[i].s;
                                printf(" is working hard now.\n");
                            }
                            else
                            {
                                se2.erase(tmp);
                                se2.insert(a[i]);
                                se1.insert(tmp);
                                cout<<a[i].s;
                                printf(" is not working now.\n");
                                cout<<tmp.s;
                                printf(" is working hard now.\n");
                            }
                        }
                        else
                        {
                            se2.insert(a[i]);
                            cout<<a[i].s;
                            printf(" is not working now.\n");
                        }
                    }
                }
                n++;
            }///++
        }
    }
    return 0;
}

C

E.Similarity of Subtrees

真心佩服那帮用递归栈都能不爆栈的大神。。。不说了,伤心题

题目要求求出相似点对对数,相似指2对子树在不同且对应深度的结点都一样

可以看做可加的向量:(d0,d1, ... ,dn)其中dk是指深度为k的结点个数

父结点的向量是其本身(1,0,0, ... )+(0,所有子结点的向量之和)

不过要是直接向量上会o(n^2)滚粗

所以搞成hash值:d0*a^0+d1*a^1+d2*a^2+...

然后发现数字太大了,要模

a>100000就可以,没有哪个向量分量超过100000

对结果模的数m>1000000000,且必须是素数,感觉不设这么大会有hash冲突

可以map搞o(nlogn)或者hash_map搞o(n)

比赛中要注意要是这种数据都能爆栈,就用非递归+stack<int>硬杠

此题还可以bfs硬撑

#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>
#include <vector>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const LL maxn=1e6+10,p=9901,mod=1e9+7;
vector<LL>G[maxn];
LL hash_v[maxn];
map<LL,LL>mp;
map<LL,LL>::iterator it;

void dfs(LL u)
{
    hash_v[u]=1;
    for(LL i=0; i<G[u].size(); i++)
    {
        LL v=G[u][i];
        dfs(v);
        hash_v[u]=(hash_v[u]+hash_v[v]*p)%mod;
    }
    mp[hash_v[u]]++;
}
int main()
{
   ///freopen("in.txt","r",stdin);
    LL n;
    LL u,v;
    while(scanf("%lld",&n)!=-1)
    {
        for(LL i=0; i<=n; i++)
        G[i].clear();
        mp.clear();
        for(LL i=1; i<n; i++)
        {
            scanf("%lld%lld",&u,&v);
            G[u].push_back(v);
        }
        dfs(1);
        LL ans=0;
        for(it=mp.begin(); it!=mp.end(); it++)
            ans+=it->second*(it->second-1)/2;
        printf("%lld\n",ans);
    }
    return 0;
}

F.Escape from the Hell

题意:有人在悬崖上的1条绳子上,

有n罐能量饮料,喝的当天可以向上爬ai米,但是若没有爬到顶点,之后会下滑bi米,不喝则不会动

与此同时,有只蜘蛛第i天会不下滑地向上ci米,且上升到人身上就会致死

问人能否逃离,第几天逃离

题解:枚举最后1天喝哪种饮料,并从饮料集合去除

把其他饮料按照a(i)-b(i)的大小排序,负数的一定没用

设sdis(i)=sdis(i-1)+c(i) pdis(i)=pdis(i)+a(i)-b(i)

找到最小的x使得

任何i<x都是pdis(i)>sdis(i)并且pdis(x-1)+a(x)>=L,就是逃离成功

枚举过的那个元素不用再重复枚举

G.Shere the Ruins Presevation

题意:把点集以1条平行于y轴且不相切任何点的直线分成2个点集,然后用栅栏把2个点集围成最小面积

题解:感觉就是对整个点集以凸包的围法画边,把整条x轴按照点集在x上的分量离散化

把整个图形按顺序分割出三角形,再把那些三角形根据占用x轴的区间把面积写在树状数组

查询时相邻区间查询因为分割而少掉的面积,最大的那个减去总面积就是解

andrew‘s monotone chain?

时间: 2024-10-24 23:44:38

2016弱校联萌十一专场10.3 遗憾题合集的相关文章

2016弱校联萌十一专场10.2

F.floyd-warshell 20000个点,距离为1的所有边求最短路 感觉就是单纯的生成树求最短路(最近公共祖先) 然后把去掉的边还原 把涉及的点bfs一下拼出最短路 #include<cstdio> #include<algorithm> #include<cstring> #define F(i,a,b) for(int i=a;i<=b;i++) #define mst(a,b) memset(a,b,sizeof(a)) using namespac

2016弱校联萌十一专场10.5

A. 因为字符串不可以交叉,其实容易解 把不同字符的可用区域看成一个区间,用类似于链表的方法连接起来 查询的就是查询到的链表数量/4(当然右区间必须属于y) 区间查询用倍增或线段树都可以 //倍增 #include <cstdio> #include <cstring> char s[100005]; int m, n, pe, pa, ps, py, dep; int pre[100005], ed[100005]; int fa[100005][20]; int main()

西南弱校联萌(1)

A. 垃圾题目毁我青春(3n+1猜想 || 模拟) Sample Input 5 Sample Output YES Hint 对于样例1:1 -> 2 -> 4 -> 8 -> 16 -> 5 Solve: 可以直接从n模拟(模拟就变成了3*n+1猜想了),所以很明显他是都是yes的 Code: 1 #pragma comment(linker, "/STACK:36777216") 2 3 #include <bits/stdc++.h>

(2016弱校联盟十一专场10.3) A.Best Matched Pair

题目链接 #include<cstdio> #include<cstring> #include<algorithm> #include<stack> using namespace std; int n,data[1005]; int cal(int x) { int tx=x; int pre=-1; while(tx) { if(pre!=-1&&tx%10-pre!=-1) return -1; pre = tx%10; tx/=10

2016弱校联盟十一专场10.3---Similarity of Subtrees(深搜+hash、映射)

题目链接 https://acm.bnu.edu.cn/v3/problem_show.php?pid=52310 problem description Define the depth of a node in a rooted tree by applying the following rules recursively: • The depth of a root node is 0. • The depths of child nodes whose parents are with

2016弱校联盟十一专场10.2---Around the World(深搜+组合数、逆元)

题目链接 https://acm.bnu.edu.cn/v3/problem_show.php?pid=52305 problem  description In ICPCCamp, there are n cities and (n−1) (bidirectional) roads between cities. The i-th road is between the ai-th and bi-th cities. It is guaranteed that cities are conne

2016弱校联盟十一专场10.2——Around the World

题目链接:Around the World 题意: 给你n个点,有n-1条边,现在这n-1条边又多增加了ci*2-1条边,问你有多少条欧拉回路 题解: 套用best定理 Best Theorem:有向图中以 i 为起点的欧拉回路个数为以 i 为根的树形图个数 ×(( 每个点 度数 −1)!). Matrix Tree Theorem:以 i 为根的树形图个数 = 基尔霍夫矩阵去掉第 i 行第 i 列的行列 式. 从某个点 i 出发并回到 i 的欧拉回路个数 = 以 i 为起点的欧拉回路个数 ×i

2016弱校联盟十一专场10.2部分题解

1/10 J. Matrix Transformation 1 /*zhen hao*/ 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 #define lson l, m, rt*2 6 #define rson m + 1, r, rt*2+1 7 #define xx first 8 #define yy second 9 10 typedef long long LL; 11 typedef unsigned long lon

2016弱校联盟十一专场10.2——Floyd-Warshall

题目链接:Floyd-Warshall 题意: 给你n个点,m条边,100>m-n>0,现在有q个询问,问你任意两点的最短距离,题目保证每条边都被连接,每条边的距离为1 题解: 首先我们可以看到边最多只比点多100个,那么我们可以先将n-1条边生成一棵树,然后用LCA来求最短距离. 然而有可能最短路在多余的这100条边上,所以我们将这100条边的两个端点到所有点的最短路用bfs预处理出来, 然后再用来更新一下答案就行. 1 #include<cstdio> 2 #include&l