2019-2020 ICPC Northwestern European Regional Programming Contest (NWERC 2019)
将每个人的排名看作是前面一个人的贡献,然后采用类似懒标记的形式优化复杂度。
int sum[N],point[N],cnt[N],pre[N],laz[N];
void solve(){
int n=read(),w=read();
laz[0]=w;
cnt[0]=n;
for(int i=0;i<w;i++){
int k=read();
for(int j=0;j<k;j++){
int x=read();
int &p=point[x];
sum[x]+=laz[p]-cnt[p+1]*(w-i)-pre[x];
laz[p]+=w-i;
--cnt[p];
++cnt[++p];
pre[x]=laz[p];
}
}
for(int i=1;i<=n;i++){
int p=point[i];
sum[i]+=laz[p]-pre[i];
double ans=sum[i]*1.0/w;
printf("%.10lf\n",ans);
}
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
所有边边权
int n,m,dis[N][N];
vector<PII>G[N];
bool res[N],vis[N][N];
bool cross(PII a, PII b, PII c) {
double xc=c.second-a.second;
double yc=a.first-c.first;
double xb=b.second-a.second;
double yb=a.first-b.first;
return xc*yb<xb*yc;
}
void Floyd() {
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
dis[i][j]=INF;
}
}
dis[0][1]=0;
for(int i=0;i<=n-2;i++){
for(int j=1;j<=n;j++){
for(auto x:G[j]){
dis[i+1][x.first]=min(dis[i+1][x.first],dis[i][j]+x.second);
}
}
}
}
void dfs(int u,int v){
res[v]=vis[u][v]=true;
if(!u)return ;
for(auto x:G[v]){
if(dis[u-1][x.first]+x.second==dis[u][v]){
if(vis[u-1][x.first])continue;
dfs(u-1,x.first);
}
}
}
void solve() {
n=read(),m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),c=read();
G[u].push_back(make_pair(v,c));
G[v].push_back(make_pair(u,c));
}
Floyd();
vector<PII>st;
for(int i=n-1;i>=1;i--){
auto x=make_pair(i,dis[i][n]);
while(st.size()>=2){
if(cross(st[st.size()-2],st[st.size()-1],x)) st.pop_back();
else break;
}
if(st.size()==1&&st.back().second>x.second)st.pop_back();
st.push_back(x);
}
for(auto x:st){
dfs(x.first,n);
}
vector<int>ans;
for(int i=1;i<=n;i++){
if(res[i])continue;
ans.push_back(i);
}
cout<<ans.size()<<'\n';
for(auto x:ans){
cout<<x<<' ';
}
}
把分数化为
从小到大的排序后,我们只需要找到一个左右能成立的点(在已排除不合法的情况下必然存在答案),同时判断能否向两端延伸。
int h[N];
void solve(){
int n=read(),k=read(),maxx=0;
for(int i=0;i<=n;i++){
h[i]=read();
}
for(int i=1;i<=n;i++){
maxx=max(maxx,h[i]-h[i-1]);
}
for(int i=1;i<=k;i++){
double g;
cin>>g;
int x=round(g*10.0);
if(maxx<x){
cout<<"-1\n";
continue;
}else{
double ans=-1;
vector<PII>vec(n+1),tmp(n+1);
for(int ii=0;ii<=n;ii++){
vec[ii]=make_pair(h[ii]-ii*x,ii);
tmp[ii]=vec[ii];
}
sort(vec.begin(),vec.end());
int l=n,r;
for(auto [x,y]:vec){
r=y;
if(l<r){
double res=0;
if(l>0)res=max(res,(double)(tmp[r].first-tmp[l].first)/fabs(tmp[l].first-tmp[l-1].first));
if(r<n)res=max(res,(double)(tmp[r].first-tmp[l].first)/fabs(tmp[r+1].first-tmp[r].first));
if(res>1.0)res=1.0;
ans=max(ans,r-l+res);
}
l=min(l,r);
}
printf("%.12lf\n",ans);
}
}
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
题目:给定一个长度为
题解:还没看懂,先贴个
#include <bits/stdc++.h>
struct Matrix {
int a00, a01, a10, a11;
};
Matrix operator*(const Matrix &lhs, const Matrix &rhs) {
Matrix res;
res.a00 = std::min(lhs.a00 + rhs.a00, lhs.a01 + rhs.a10);
res.a01 = std::min(lhs.a00 + rhs.a01, lhs.a01 + rhs.a11);
res.a10 = std::min(lhs.a10 + rhs.a00, lhs.a11 + rhs.a10);
res.a11 = std::min(lhs.a10 + rhs.a01, lhs.a11 + rhs.a11);
return res;
}
struct SegmentTree {
int n;
std::vector<Matrix> t;
SegmentTree(int n) : n(n), t(4 * n) {
build(1, 0, n);
}
void build(int p, int l, int r) {
t[p].a00 = t[p].a11 = r - l;
t[p].a01 = t[p].a10 = 1e9;
if (r - l == 1)
return;
int m = (l + r) / 2;
build(2 * p, l, m);
build(2 * p + 1, m, r);
}
void modify(int p, int l, int r, int x, int y) {
if (r - l == 1) {
if (y == 0) {
t[p].a10 = 0;
} else {
t[p].a01 = 0;
}
return;
}
int m = (l + r) / 2;
if (x < m) {
modify(2 * p, l, m, x, y);
} else {
modify(2 * p + 1, m, r, x, y);
}
t[p] = t[2 * p] * t[2 * p + 1];
}
void modify(int x, int y) {
modify(1, 0, n, x, y);
}
int get() {
return std::min({t[1].a00, t[1].a01, t[1].a10, t[1].a11});
}
};
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, c, r;
std::cin >> n >> c >> r;
int64_t ans = 1ll * n * r;
SegmentTree t(n);
std::vector<std::tuple<int, int, int>> events;
events.reserve(2 * n);
for (int i = 0; i < n; ++i) {
int x;
std::cin >> x;
events.emplace_back(std::max(0, 1 - x), i, 0);
events.emplace_back(std::max(0, 1 + x), i, 1);
}
std::sort(events.begin(), events.end());
for (auto [a, x, y] : events) {
t.modify(x, y);
ans = std::min(ans, 1ll * a * c + 1ll * t.get() * r);
}
std::cout << ans << "\n";
return 0;
}
本文作者:EdGrass
本文链接:https://www.cnblogs.com/edgrass/p/17768760.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步