A:显然答案与原数的差不会很大。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,ans[1000],u;
int calc(int n)
{
int s=0;
while (n) s+=n%10,n/=10;
return s;
}
signed main()
{
n=read();
for (int i=1;i<=min(n,1000);i++)
{
int x=n-i;
if (calc(x)==i) ans[++u]=x;
}
cout<<u<<endl;
for (int i=1;i<=u;i++) cout<<ans[i]<<endl;
return 0;
//NOTICE LONG LONG!!!!!
}

  B:即求不处于最右端的位置中有多少个1,随便维护。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,a[N],ans;
bool flag[N];
signed main()
{
n=read();
for (int i=1;i<=n;i++) a[i]=read();
cout<<1<<' ';ans=1;int suf=n+1;
for (int i=1;i<=n;i++)
{
flag[a[i]]=1;
if (suf==a[i]+1)
{
suf=a[i];
while (flag[suf-1]) suf--;
}
ans++;cout<<ans-(n-suf+1)<<' ';
}
return 0;
//NOTICE LONG LONG!!!!!
}

  C:按位考虑,倒序贪心,必须改(即前缀与后一个串相同且该位较大)的时候才改。全部扫过一遍后可能仍不合法,需要按同样的做法重新扫一遍,并且可以证明扫两遍之后依旧不合法则无解。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,len,p[N];
bool flag[N],same[N];
vector<int> a[N],pre[N];
bool astb(int i,int j,int x)
{
if (a[i].size()<=x) return 1;
if (a[j].size()<=x) return 0;
if (flag[a[j][x]]!=flag[a[i][x]]) return flag[a[i][x]];
else return a[i][x]<=a[j][x];
}
void error(){cout<<"No";exit(0);}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
#endif
n=read(),m=read();
for (int i=1;i<=n;i++)
{
int m=read();len=max(len,m);
for (int j=0;j<m;j++) pre[i].push_back(p[j]),p[j]=i,a[i].push_back(read());
}
for (int t=3;t;t--)
{
for (int i=1;i<n;i++) same[i]=1;
for (int i=0;i<len;i++)
{
for (int k=p[i];k>=1;k=pre[k][i])
if (k<n)
{
if (same[k]&&!astb(k,k+1,i))
{
flag[a[k][i]]=1;
if (!astb(k,k+1,i)) error();
}
same[k]&=astb(k,k+1,i)&&astb(k+1,k,i);
}
}
}
for (int i=1;i<n;i++)
{
int f=-1;
for (int j=0;j<min(a[i].size(),a[i+1].size());j++)
{
if (a[i][j]!=a[i+1][j])
{
if (flag[a[i][j]]==flag[a[i+1][j]]) f=a[i][j]<a[i+1][j];
else f=flag[a[i][j]];
break;
}
}
if (f==0) error();
if (f==-1) if (a[i].size()>a[i+1].size()) error();
}
cout<<"Yes"<<endl;
int cnt=0;for (int i=1;i<=m;i++) if (flag[i]) cnt++;
cout<<cnt<<endl;
for (int i=1;i<=m;i++) if (flag[i]) cout<<i<<' ';
return 0;
//NOTICE LONG LONG!!!!!
}

  D:考虑枚举区间max,显然只要区间内存在一个数在max不为0的一位为1即可。随便预处理一下就完了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,a[N],pre[N][32],suf[N][32],PRE[N],SUF[N];
ll ans;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++)
{
for (int j=0;j<32;j++) pre[i][j]=pre[i-1][j];
for (int j=0;j<32;j++)
if (a[i-1]&(1<<j)) pre[i][j]=i-1;
}
for (int j=0;j<32;j++) suf[n+1][j]=n+1;
for (int i=n;i>=1;i--)
{
for (int j=0;j<32;j++) suf[i][j]=suf[i+1][j];
for (int j=0;j<32;j++)
if (a[i+1]&(1<<j)) suf[i][j]=i+1;
}
a[0]=a[n+1]=1000000010;
for (int i=1;i<=n;i++)
{
int j=i-1;
while (a[j]<a[i]) j=PRE[j];
PRE[i]=j;
}
SUF[n+1]=n+1;
for (int i=n;i>=1;i--)
{
int j=i+1;
while (a[j]<=a[i]) j=SUF[j];
SUF[i]=j;
} for (int i=1;i<=n;i++)
{
int x=PRE[i],y=SUF[i];int u=PRE[i],v=SUF[i];
for (int j=0;j<32;j++)
if (!(a[i]&(1<<j))) u=max(u,pre[i][j]),v=min(v,suf[i][j]);
ans+=1ll*(SUF[i]-i)*(u-PRE[i])+1ll*(i-u)*(SUF[i]-v);
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}

  E:显然二分答案。考虑设f[i][0/1]表示第i个由A/B送是否合法,因为此时另一个人的位置并不重要。转移考虑另一个人上次送货是在哪,但这个转移无法实现,因为转移区间并不连续。但容易发现如果顺推过去就是连续的了。st表预处理区间minmax,二分得到转移边界,bit优化转移即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
#define inf 1000000000
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,p,q,a[N][2],f[N][2],mn[N][18],mx[N][18],LG2[N],tree[N][2];
int query_max(int l,int r)
{
if (l>r) return 0;
return max(mx[l][LG2[r-l+1]],mx[r-(1<<LG2[r-l+1])+1][LG2[r-l+1]]);
}
int query_min(int l,int r)
{
if (l>r) return inf;
return min(mn[l][LG2[r-l+1]],mn[r-(1<<LG2[r-l+1])+1][LG2[r-l+1]]);
}
void add(int i,int k,int x){while (k<=n+1) tree[k][i]+=x,k+=k&-k;}
int query(int i,int k){int s=0;while (k) s+=tree[k][i],k-=k&-k;return s;}
bool check(int k)
{
memset(f,0,sizeof(f));
memset(tree,0,sizeof(tree));
//cout<<k<<endl;
f[0][0]=f[0][1]=1;
for (int i=0;i<=n;i++)
for (int j=0;j<2;j++)
{
if (i) f[i][j]=(query(j,i)>0);
if (f[i][j])
{
int l=i+1,r=n,x=i;
while (l<=r)
{
int mid=l+r>>1;
if (query_max(i+1,mid)-a[i][j]<=k&&a[i][j]-query_min(i+1,mid)<=k) x=mid,l=mid+1;
else r=mid-1;
}
//cout<<i<<' '<<j<<' '<<x<<' '<<a[i][j]<<' '<<query_max(i+1,x)<<' '<<query_min(i+1,x)<<endl;
add(j^1,i+1,1),add(j^1,x+1,-1);
}
}
return f[n][0]|f[n][1];
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),a[0][0]=read(),a[0][1]=read();
for (int i=1;i<=n;i++) mn[i][0]=mx[i][0]=a[i][0]=a[i][1]=read();
for (int j=1;j<18;j++)
for (int i=1;i<=n;i++)
mx[i][j]=max(mx[i][j-1],mx[min(n,i+(1<<j-1))][j-1]),
mn[i][j]=min(mn[i][j-1],mn[min(n,i+(1<<j-1))][j-1]);
for (int i=2;i<=n;i++)
{
LG2[i]=LG2[i-1];
if ((2<<LG2[i])<=i) LG2[i]++;
}
int l=abs(a[0][0]-a[0][1]),r=inf,ans;
while (l<=r)
{
int mid=l+r>>1;
if (check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}

  F:按价值从大到小排序,逐个考虑,显然如果选择某个公主后仍然存在匹配方案,就应该将其选中,因为这至多会使后面的一位公主无法匹配,不选一定不优。

  然后考虑动态判断合法性。显然这是一个二分图匹配问题,但当然不能直接跑。注意到我们需要知道的只是二分图一侧是否存在完美匹配,考虑Hall定理,考虑该侧每个点集在另一侧与几个点相连。由于该侧的点只会与另一侧两个点相连,如果向一个连通块中新加入一个点,不会使得该连通块的任何与其在另一侧有公共点的点集更容易满足定理。所以只要整个连通块是满足Hall定理的,该侧所有点集也一定满足。于是只要用并查集维护二分图每个连通块两侧点的数量差即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,ans,fa[N],size[N];
struct data
{
int x,y,z;
bool operator <(const data&a) const
{
return z>a.z;
}
}a[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
m=read(),n=read();
for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].z=read();
sort(a+1,a+n+1);
for (int i=1;i<=m;i++) fa[i]=i,size[i]=1;
for (int i=1;i<=n;i++)
{
int p=find(a[i].x),q=find(a[i].y);
if (p==q)
{
if (size[p]>=1) size[p]--,ans+=a[i].z;
}
else
{
if (size[p]|size[q]) size[p]+=size[q]-1,fa[q]=p,ans+=a[i].z;
}
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}

  

Codeforces Round #441 Div. 1的更多相关文章

  1. Codeforces Round #441 (Div. 2)【A、B、C、D】

    Codeforces Round #441 (Div. 2) codeforces 876 A. Trip For Meal(水题) 题意:R.O.E三点互连,给出任意两点间距离,你在R点,每次只能去 ...

  2. Codeforces Round #441 (Div. 2)

    Codeforces Round #441 (Div. 2) A. Trip For Meal 题目描述:给出\(3\)个点,以及任意两个点之间的距离,求从\(1\)个点出发,再走\(n-1\)个点的 ...

  3. [日常] Codeforces Round #441 Div.2 实况

    上次打了一发 Round #440 Div.2 结果被垃圾交互器卡掉 $200$ Rating后心情复杂... 然后立了个 Round #441 要翻上蓝的flag QAQ 晚饭回来就开始搞事情, 大 ...

  4. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) D. Sorting the Coins

    http://codeforces.com/contest/876/problem/D 题意: 最开始有一串全部由"O"组成的字符串,现在给出n个数字,指的是每次把位置n上的&qu ...

  5. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) C. Classroom Watch

    http://codeforces.com/contest/876/problem/C 题意: 现在有一个数n,它是由一个数x加上x每一位的数字得到的,现在给出n,要求找出符合条件的每一个x. 思路: ...

  6. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) B. Divisiblity of Differences

    http://codeforces.com/contest/876/problem/B 题意: 给出n个数,要求从里面选出k个数使得这k个数中任意两个的差能够被m整除,若不能则输出no. 思路: 差能 ...

  7. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) A. Trip For Meal

    http://codeforces.com/contest/876/problem/A 题意: 一个人一天要吃n次蜂蜜,他有3个朋友,他第一次总是在一个固定的朋友家吃蜂蜜,如果说没有吃到n次,那么他就 ...

  8. Codeforces Round #441 (Div. 2, by Moscow Team Olympiad)

    A. Trip For Meal 题目链接:http://codeforces.com/contest/876/problem/A 题目意思:现在三个点1,2,3,1-2的路程是a,1-3的路程是b, ...

  9. Codeforces Round #441(Div.2) F - High Cry

    F - High Cry 题目大意:给你n个数,让你找区间里面所有数或 起来大于区间里面最大数的区间个数. 思路:反向思维,找出不符合的区间然后用总数减去.我们找出每个数掌控的最左端 和最右端,一个数 ...

随机推荐

  1. SQL Server 分析函数和排名函数

    分析函数基于分组,计算分组内数据的聚合值,经常会和窗口函数OVER()一起使用,使用分析函数可以很方便地计算同比和环比,获得中位数,获得分组的最大值和最小值.分析函数和聚合函数不同,不需要GROUP ...

  2. 开源Dapper的Lambda扩展-Sikiro.Dapper.Extension V2.0

    前言 去年我在业余时间,自己整了一套dapper的lambda表达式的封装,原本是作为了一个个人的娱乐项目,当时也只支持了Sql Server数据库.随之开源后,有不少朋友也对此做了试用,也对我这个项 ...

  3. 美橙互联SSL 部署到IIS 7以上

    前言:立秋已至,汗流浃背,感觉夏天正到最热的时候...广州某一“著名”大厦 老板:穆德(我),现在要开发个微信小程序.开搞吧. 我:纳尼?好吧.需要购买SSL证书(⊙o⊙)? 老板:神马鬼,有没有免费 ...

  4. jqGrid之treeGrid及行拖拽

    单纯的做个小记录 今天做功能用到了jqGrid里面的treeGrid,遇到几个问题,这里做下记录 treeGrid 树表格的应用在官网给出了很直白的例子: 1.http://blog.mn886.ne ...

  5. Dockerfile centos7_tomcat7.0.64_jdk7u80

    FROM centos:7 MAINTAINER jiangzhehao WORKDIR /tmp RUN yum -y install net-tools ADD jdk-7u80-linux-x6 ...

  6. python-BeautifulSoup库详解

    快速使用 通过下面的一个例子,对bs4有个简单的了解,以及看一下它的强大之处: from bs4 import BeautifulSoup html = ''' <html><hea ...

  7. Applese 的毒气炸弹 G 牛客寒假算法基础集训营4(图论+最小生成树)

    链接:https://ac.nowcoder.com/acm/contest/330/G来源:牛客网 Applese 的毒气炸弹 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262 ...

  8. Python迭代器与格式化

    三元运算 对if-else判断的简写 >>> age = 18 >>> res = "You are so young!" if age < ...

  9. Pair Project

    以前只是一个人完成一个项目,不论什么都是,现在突然要两个人一起来写, 听上去挺稀奇的,也挺简单的,可惜了就是“听上去”而已.我认为这也是一种技术啊~ 我跟我的搭档研究了好久好久,选择了好久,然后也选了 ...

  10. IntelliJ IDEA/WebStrom破解及JDK配置

    title: IntelliJ IDEA/WebStrom破解及JDK配置 (一)破解 破解步骤 第一步:下载破解补丁 第二步:修改配置文件 第三步:重启IntelliJ IDEA/WebStrom填 ...