2016暑假集训补题系列

Codefoeces 496E(贪心+二分)

题意:一场演出有N段演奏,每段演奏都有一个音域,有M个演唱家,每个演唱家也分别有自己的音域,而且同一场演出中能演唱最多K次。问是否能够使所有的演奏都能进行,如果能应该怎样分配演唱顺序。

思路:先排个序,把每段演奏以及每个人都按照音域[L,R],R小的优先,相同的情况下,L小的优先。然后对每个人依次操作。每次操作把演奏的R小于等同于该演唱者的R的部分放入multiset中(这里要用到其自动排序和可二分查找的功能),然后二分找到集合中刚好满足演奏的L大于等于演唱者L的位置,然后依次往后找知道没有或者该演唱者次数已够。并把这之中的所有元素删除。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
struct node{
    int l,r,k,pos;
    friend bool operator<(node x,node y){
        return x.l<y.l;
    }
} a[100005],b[100005];
bool cmp(node a,node b){
    if(a.r==b.r) return a.l<b.l;
    return a.r<b.r;
};
int ans[100005],cnt;
int main(){
    int n,m;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[i].l,&a[i].r);
        a[i].pos=i;
    }
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].k);
        b[i].pos=i;
    }
    sort(a,a+n,cmp);
    sort(b,b+m,cmp);
    multiset<node> s;
    int cnt=0,cur=0;
    for(int i=0;i<m;i++){
        while(cur<n&&a[cur].r<=b[i].r){
            s.insert(a[cur]);
            cur++;
        }
        multiset<node>::iterator e,top;
        top=s.lower_bound(b[i]);
        e=s.lower_bound(b[i]);
        int p=0;
        while(!s.empty()&&e!=s.end()&&p<b[i].k){
            node u=*e;
            ans[u.pos]=b[i].pos;
            e++; p++; cnt++;
        }
        s.erase(top,e);
    }
    if(cnt!=n) printf("NO\n");
    else{
        printf("YES\n");
        for(int i=0;i<n;i++)
            printf("%d ",ans[i]+1);
    }

    return 0;
}

Psong

时间: 2024-08-03 19:24:27

2016暑假集训补题系列的相关文章

2016暑假集训补题系列——POJ 1475

POJ 1475 Pushing Boxes 题意:模拟推箱子游戏给出一个二维图,S表示人的位置,B表示箱子位置,T表示目标位置.要求最短输出路径大写字母代表推,小写字母代表走. 思路:BFS+BFS,首先对箱子进行BFS,每一次在加入新的节点时对人再进行一次BFS,找到他走到需要推箱子的地方的最小路径.(最开始不知道怎么记录路径,之前也几乎不用String,结果如此好用,还可以直接加...) #include<cstdio> #include<algorithm> #includ

hdu5017:补题系列之西安网络赛1011

补题系列之西安网络赛1011 题目大意:给定一个椭球: 求它到原点的最短距离. 思路: 对于一个椭球的标准方程 x^2/a^2 + y^2/b^2 +z^2/c^2=1 来说,它到原点的最短距离即为min(a,b,c) 所以我们需要把原方程化为标准型. 这时候线代就排上用场了,注意到原方程是一个二次型. 化为标准型 1/(k1)*x^2+1/(k2)*y^2+1/(k3)*z^2=1 后  min(k1,k2,k3)即为答案 而这里的1/k1,1/k2,1/k3 就是二次型矩阵的特征值 如何求特

2016暑假集训训练2 C题 食物链

带权并查集傻逼题 用拆点方法草过. 拆点代码: # include <stdio.h> # include <string.h> int set[150005], n, k, d; int find(int x) { int s, temp; for (s=x; set[s]>=0; s=set[s]) ; while (s != x) { temp = set[x]; set[x] = s; x = temp; } return s; } void union_set(in

2016暑假集训训练2 H题 Frosh Week

求逆序数的傻逼题. 用归并排序或者树状数组或者线段树 归并排序代码: # include<stdio.h> # define MAXN 500100 int a[MAXN],b[MAXN]; long long ans; void merge(int l, int r) { int k, p, q; if(l == r) return; int mid= (l+r)>>1; merge(l,mid); merge(mid+1,r); p = l; q = mid+1; k = l;

2016暑假集训训练2 I题 Doing Homework again

傻逼贪心题. 先按照扣分从大到小排序,分数相同则按照截止日期从小到大排序.. 然后按顺序,从截止日期开始往前找没有占用掉的时间. 如果找不到了,则加到罚分里面. # include <stdio.h> # include <stdlib.h> # include <string.h> int h[1005][2], n, visit[1005]; int comp(const void * a, const void * b) { return *(((int*)b)+

2016暑假集训训练2 N题 Play on Words

水题不解释.... # include <stdio.h> # include <string.h> int dee[26], set[26], node[26], n; char s[1002]; int find(int x) { int s, temp; for (s=x; set[s]>=0; s=set[s]) ; while (s!=x) { temp = set[x]; set[x] = s; x = temp; } return s; } void union

2016HUAS暑假集训训练题 G - Oil Deposits

Description The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It

2016HUAS暑假集训训练题 F - 简单计算器

Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔.没有非法表达式.当一行中只有0时输入结束,相应的结果不要输出. Output 对每个测试用例输出1行,即该表达式的值,精确到小数点后2位. Sample Input 1 + 2 4 + 2 * 5 - 7 / 11 0 Sample Output 3.00 13.36 分析: 本题

大连廿四2016暑假集训day1-T3(quick select&amp;linear select)

3 kth3.1 Description给定 n 个不超过 10^9 的正整数,请线性时间选择算法 (linear select)求其中的第 k 大值.3.2 Input第一行两个整数 n,k. 第二行 n 个整数,表示题目中的那 n 个正整数.3.3 Output一行,表示答案.3.4 Sample Input10 3 2 4 7 3 5 6 9 6 1 83.5 Sample Output73.6 Constraints一共 10 个测试点,每个测试点 10 分,只有当你的答案与标准答案完全