http://codeforces.com/contest/276/problem/C 原题连接
解题说明:题目的意思是有若干对区间和的查询,问如何重组数组使查询结果的和最大。
我的解法就是将对应的频率排序之后在求(求频率那里需要点思维嘻嘻
直接贴代码了
#include <algorithm> #include <stack> #include <istream> #include <stdio.h> #include <map> #include <math.h> #include <vector> #include <iostream> #include <queue> #include <string.h> #include <set> #include <cstdio> #define FR(i,n) for(int i=0;i<n;i++) #define MAX 2005 #define mkp pair <int,int> using namespace std; const int maxn = 4e5 + 40; typedef long long ll; const int inf = 0x3fffff; void read(ll &x) { char ch; bool flag = 0; for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar()); for (x = 0; isdigit(ch); x = (x << 1) + (x << 3) + ch - 48, ch = getchar()); x *= 1 - 2 * flag; } ll val[maxn]; int vis[maxn]; struct inof{ ll l; bool flag; }fuck[maxn]; bool cmp(inof a,inof b) { return a.l<b.l; } int res[maxn]; int main() { ll n,m; memset(vis,0,sizeof(vis)); read(n),read(m); for(int i=1;i<=n;i++){ read(val[i]); } int top = 0; while(m--){ // ll l,r; read(fuck[top].l); fuck[top].flag=1; top++; read(fuck[top].l); fuck[top].l++; fuck[top].flag=0; top++; //read(l),read(r); //vis[l]++,vis[r+1]--; } sort(fuck,fuck+top,cmp); int sub = 0; int maxx = 0; for(int i=0;i<top;i++) { if(i)vis[sub]+=fuck[i].l-fuck[i-1].l; if(fuck[i].flag)sub++; else sub--; maxx=max(maxx,sub); } ll ans = 0; sort(val+1,val+n+1); // sort(vis,vis+maxx+1); int temp = n; for(int i=maxx;i>=0;i--) { if(vis[i]) { while(temp>=1&&vis[i])vis[i]--,ans+=val[temp]*i,temp--; } if(temp==0)break; } cout<<ans<<endl; return 0; }