Codeforces Round #460 D. Karen and Cards

Description

Karen just got home from the supermarket, and is getting ready to go to sleep.

After taking a shower and changing into her pajamas, she looked at her shelf and saw an album. Curious, she opened it and saw a trading card collection.
She recalled that she used to play with those cards as a child, and, although she is now grown-up, she still wonders a few things about it.
Each card has three characteristics: strength, defense and speed. The values of all characteristics of all cards are positive integers. The maximum possible strength any card can have is p, the maximum possible defense is q and the maximum possible speed is r.
There are n cards in her collection. The i-th card has a strength ai, defense bi and speed ci, respectively.
A card beats another card if at least two of its characteristics are strictly greater than the corresponding characteristics of the other card.
She now wonders how many different cards can beat all the cards in her collection. Two cards are considered different if at least one of their characteristics have different values.
题面

Solution

考虑枚举一维,假设枚举\(c\),讨论\(c\)与某个\(c_i\)的关系
如果\(c>c_i\)那么 \(a>a_i | b>b_i\),满足一项即可
如果\(c<=c_i\),需满足 \(a>a_i \& b>b_i\)
这两个条件分别对应 矩形去掉一个小矩形 和 矩形 这两种图形

考虑多个矩形的情况:
如果所有矩形都是情况1,那么情况\(1\)就是所有矩形的并的补集
按第一维排序之后,第二位一定是递减序列,用一个单调栈即可维护

如果c取\(maxc\)的时候,得出的图形就是上面所求出的
考虑c减少时的情况,那么就会出现情况2
原图形就变成一个矩形和剩余矩形的交
我们可以通过减去补集来求出
按卡片的c属性从大到小枚举,维护轮廓即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=500010;
int n,A,B,C;
struct node{
    int a,b,c;
}p[N];
inline bool ca(const node &i,const node &j){
    if(i.a!=j.a)return i.a<j.a;
    return i.b<j.b;
}
inline bool cc(const node &i,const node &j){return i.c>j.c;}
int st[N],top=0,bx[N],by[N];
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  scanf("%d%d%d%d",&n,&A,&B,&C);
  for(int i=1;i<=n;i++)scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c);
  sort(p+1,p+n+1,ca);
  for(int i=1;i<=n;i++){
      while(top && p[st[top]].b<p[i].b)top--;
      st[++top]=i;
  }
  ll tot=0,ans=0;st[top+1]=0;
  for(int i=1;i<=top;i++){
      tot+=1ll*p[st[i]].b*(p[st[i]].a-p[st[i-1]].a);
      for(int j=p[st[i-1]].a+1;j<=p[st[i]].a;j++)by[j]=p[st[i]].b;
      for(int j=p[st[i]].b;j>p[st[i+1]].b;j--)bx[j]=p[st[i]].a;
  }
  tot=1ll*A*B-tot;
  sort(p+1,p+n+1,cc);
  for(int i=C,j=1,x=1,y=1;i>=1;i--){
      for(;j<=n && p[j].c>=i;j++){
          while(x<=p[j].a)tot-=B-max(by[x],y-1),x++;
          while(y<=p[j].b)tot-=A-max(bx[y],x-1),y++;
      }
      ans+=tot;
  }
  cout<<ans<<endl;
  return 0;
}

原文地址:https://www.cnblogs.com/Yuzao/p/8447425.html

时间: 2024-10-02 16:43:40

Codeforces Round #460 D. Karen and Cards的相关文章

Codeforces Round #424 (Div. 2) E. Cards Sorting(线段树)

题目链接:Codeforces Round #424 (Div. 2) E. Cards Sorting 题意: 将n个数放进一个队列,每次检查队首,看看是不是队列中最小的数,如果是就扔掉,如果不是就放到队尾. 这样直到队列为空,为需要操作多少次. 题解: 考虑用两个指针模拟,最开始now指针指向第一个数,然后nxt指针指向下一个将要被删除的数. 然后我们要算出这里需要移动多少步,然后删掉这个数,一直重复操作,直到将全部的数删完. nxt指针可以用set来维护,now指针可以用并查集来维护. 计

Codeforces Round #490 (Div. 3) F - Cards and Joy

F - Cards and Joy 思路:比较容易想到dp,直接dp感觉有点难,我们发现对于每一种数字要处理的情况都相同就是有 i 张牌 要给 j 个人分, 那么我们定义dp[ i ][ j ]表示 i 张牌给 j 个人分最大的价值可以得到dp方程如下: dp[ i ][ j ] = max(dp[ i - u ][ j - 1 ] + f[ u ] )   u <= k 暴力转移就好了. #include<bits/stdc++.h> #define LL long long #def

Codeforces Round #460 (Div. 2) 919A. Supermarket 919B. Perfect Number 919C. Seat Arrangements

这场cf有点意思,hack场,C题等于1的特判hack很多人(我hack成功3个人,上分了,哈哈哈,咳咳...) D题好像是树形dp,E题好像是中国剩余定理,F题好像还是dp,具体的不清楚,最近dp的题目好多,一会滚去学dp. 写A,B,C的题解. A. Supermarket time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output

Codeforces Round #460 (Div. 2)_D. Substring_[dp][拓扑排序]

题意:一个有向图,每个结点 被赋予一个小写字母,一条路径的value等与这条路径上出现次数最多的字母的数目,求该图的最大value 比赛时,用dfs超时,看官方题解用的dp和拓扑排序,a--z用0-25表示,用dp[i][j]表示以第i个结点结尾的路径上第j个字母出现的次数 拓扑排序每排到一个点,就用该点的dp去更新与它相邻点的dp,最开始入度为0的点特殊处理了一下,dp过程中同步更新结果res 也复习了一下拓扑排序 #include<iostream> #include<cstdio&

Codeforces Round #460 (Div. 2)

A 签到 B 题意 定义:一个数(没有前缀0)的各个位数之和为10位"perfec"数,问第k个"perfect"数位多少(1<=k<=1e5) 分析 一开始找错了,以为会超过1e9,通过理性的分析不难发现,最大不超过1e9,强行打个表即可 C 签到 D 题意 n个点m条边的有向图,每个点有一个数字(可以重复,0~25),定义一条路径的权值为该路径出现数字最多的数字的次数,若有环输出-1,否则输出最大值 分析 思路:首先直接dfs肯定不行,最坏情况n^2

Codeforces Round #460 (Div. 2) 919 笔记

A. Supermarket 输入n,m, (1?≤?n?≤?5?000, 1?≤?m?≤?100)表示n组价格数据和目标重量m 接下来n组价格数据,表示为a元b千克,每组无限取 求最小花费 B. Perfect Number 输入k,1?≤?k?≤?10?000,求第k个完美数 完美数定义为数位和=10 (tutorial中说难度可以升级为k<1e18)->用数位dp可解 C. Seat Arrangements 输入n,m,k (1?≤?n,?m,?k?≤?2?000)表示nm的课室,有k

Codeforces Round #460 (Div. 2) B Perfect Number(二分+数位dp)

题目传送门 B. Perfect Number time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output We consider a positive integer perfect, if and only if the sum of its digits is exactly 1010. Given a positive integ

Codeforces Round #419 (Div. 2) E. Karen and Supermarket(树形DP)

题目链接:Codeforces Round #419 (Div. 2) E. Karen and Supermarket 题意: 有n件物品,每个物品有一个价格,和一个使用优惠券的价格,不过这个优惠券有一个限制,必须要在第x个使用后才可以使用.现在有m的钱,问最多能买多少个物品. 题解: 每个优惠券都只与一个券有关,所以根据这个关系就可以构成一棵树. 考虑树形dp,dp[i][j][k(0|1)]表示第i个节点所构成的子树中买了j个物品,使用优惠券和不使用优惠券的最少钱. 转移方程看代码详细解释

queue+模拟 Codeforces Round #304 (Div. 2) C. Soldier and Cards

题目传送门 1 /* 2 题意:两堆牌,每次拿出上面的牌做比较,大的一方收走两张牌,直到一方没有牌 3 queue容器:模拟上述过程,当次数达到最大值时判断为-1 4 */ 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <cstring> 9 #include <string> 10 #include <stack> 11 #in