题目链接:http://codeforces.com/contest/1181
题意:两个人各a,b元,一个物品价值c元,求两个人一起最多可以买多少该物品,以及两人之间最小需要传递多少元。
#include
using namespace std;
#define ll long long
int main()
{
ll a,b,c;
while(~scanf("%I64d%I64d%I64d",&a,&b,&c)){
ll d=(a+b)/c;
ll e;
if((a/c+b/c)==d)
e=0;
else{
e=min(c-a%c,c-b%c);
}
printf("%I64d %I64d\n",d,e);
}
return 0;
}
题意:把一个无前缀0的数拆成两个无前缀0的数,将这两个数相加,求最小结果。
#include
using namespace std;
#define ll long long
const int maxn=100010;
char s[maxn];
char a[maxn],b[maxn];
char c[maxn],c2[maxn];
int n;
void cal2(char c[],char c2[])
{
int m1=strlen(c),m2=strlen(c2);
if(m1>m2) return;
bool flag=0;
for(int i=m1-1;i>=0;i--){
if(c[i]!=c2[i]){
if(c[i]>c2[i])
flag=1;
break;
}
}
if(flag)
memcpy(c,c2,sizeof(c2));
}
void cal(char c[],int m)// a+b->c
{
// memset(a,0,sizeof(a));
// memset(b,0,sizeof(b));
for(int i=0;i<m;i++) a[i]=s[i];
for(int i=m;i<n;i++) b[i-m]=s[i];
int len1=m,len2=n-m;
a[len1]=b[len2]='\0';
int tot=0,flag=0,i=len1-1,j=len2-1;
// printf("cur_m:%d a:%s b:%s\n",m,a,b);//
while(i>=0&&j>=0){
c[tot++]=(a[i]-'0'+b[j]-'0'+flag)%10+'0';
flag=(a[i]-'0'+b[j]-'0'+flag)/10;
i--;j--;
}
while(i>=0){
c[tot++]=(a[i]-'0'+flag)%10+'0';
flag=(a[i]-'0'+flag)/10;
i--;
}
while(j>=0){
c[tot++]=(b[j]-'0'+flag)%10+'0';
flag=(b[j]-'0'+flag)/10;
j--;
}
c[tot]='\0';
// printf("cur_c:");
// for(int i=tot-1;i>=0;i--) printf("%c",c[i]);
// printf("\n");
}
void solve(int m1,int m2)
{
while(s[m1]=='0'&&s[m2]=='0'){
m1--;m2++;
}
// printf("m1:%d m2:%d\n",m1,m2);
if(s[m1]=='0')
cal(c,m2);
else if(s[m2]=='0')
cal(c,m1);
else{
cal(c,m1);
cal(c2,m2);
cal2(c,c2);
}
}
int main()
{
int m,m1,m2;
while(~scanf("%d",&n)){
scanf("%s",s);
m=n/2;
if(n%2==0){
if(s[m]=='0'){
m1=m;
m2=m;
solve(m1,m2);
}else{
cal(c,m);
}
}else{
m1=m;m2=m+1;
solve(m1,m2);
}
int len=strlen(c);
for(int i=len-1;i>=0;i--) printf("%c",c[i]);
printf("\n");
}
return 0;
}
题意:给一个含nm个点的图,每个图最多有26个类型,分别为a-z;一个子图为flag图,如果该图由上中下三部分的类型点组成,三种类型两两互不相同,且其高度都相同,求一个nm的图,有多少个flag子图。
题解:st表,求原图s[][]的后缀之和suf[][],然后对于每一列的累积suf值,我们用st表,查询每一列最小值,对应每个从当前列开始,行标为[l,r]时flag图有多少个。为了方便,把矩阵转置来处理。详见代码。
参考思路来自 xyq0220
#include
using namespace std;
#define ll long long
const int maxn=1010;
char s[maxn][maxn];
int suf[maxn][maxn];
int st[maxn][maxn][20];
int n,m;
void init()
{
for(int i=1;i<=m;i++)
for(int k=1;(1<<k)<=n;k++)
for(int j=1;j+(1<<k)-1<=n;j++)
st[i][j][k]=min(st[i][j][k-1],st[i][j+(1<<k-1)][k-1]);
}
int cal(int i,int l,int r)
{
int m=log2(r-l+1);
return min(st[i][l][m],st[i][r-(1<<m)+1][m]);
}
int main()
{
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++)
scanf("%s",s[i]+1);
for(int i=1;i<=n;i++){
suf[i][m+1]=0;
for(int j=m;j>=1;j--){
if(s[i][j]==s[i][j+1])
suf[i][j]=suf[i][j+1]+1;
else
suf[i][j]=1;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
st[j][i][0]=suf[i][j];
init();
ll ans=0;
vector<int> ve;
for(int i=1;i<=m;i++){
ve.clear();
for(int j=1;j<=n;j++){
int k=j;
while(s[k][i]==s[j][i]) k++;
ve.push_back(k-j);
j=k-1;
}
int k=1;
for(int j=0;j+2<ve.size();j++){
if(ve[j]>=ve[j+1]&&ve[j+1]<=ve[j+2]){
int l=k+ve[j]-ve[j+1],r=k+ve[j]+2*ve[j+1]-1;
ans+=1LL*cal(i,l,r);
}
k+=ve[j];
}
}
printf("%I64d\n",ans);
}
return 0;
}
//By natofp, contest: Codeforces Round #567 (Div. 2), problem: (D)
//By natofp, contest: Codeforces Round #567 (Div. 2), problem: (D) Irrigation
#include
#include
using namespace std;
int n,m,q;
const int nax=5e5+5;
int a[nax];
long long int p[nax];
long long int k;
vector<pair<int,int> > xd;
int ans[nax];
const int roz=(1<<21);
int tree[roz];
long long int ile(int l,int r)
{
if(l==0) return p[r];
return p[r]-p[l-1];
}
void add(int pos,int val)
{
pos+=roz/2;
while(pos>=1)
{
tree[pos]++;
pos/=2;
}
}
bool czy(long long int x)
{
//czy pefix[0....x] BEDZIE ROWNY;
long long int naj=xd[x].first;
naj*=(x+1);
naj-=ile(0,x);
if(naj>=k) return false;
return true;
}
int kty(int z)
{
int pos=1;
while(1)
{
if(pos>=roz/2) return pos-roz/2;
if(tree[pos*2]<z)
{
z-=tree[pos*2];
pos=pos*2+1;
}
else
{
pos*=2;
}
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
memset(tree,0,sizeof tree);
cin>>n>>m>>q;
memset(a,0,sizeof a);
memset(p,0,sizeof p);
for(int i=1;i<=n;i++)
{
int x; cin>>x;
a[x]++;
}
for(int i=1;i<=m;i++)
{
xd.push_back({a[i],i});
}
sort(xd.begin(),xd.end());
p[0]=xd[0].first;
for(int i=1;i<m;i++)
{
p[i]=p[i-1]+xd[i].first;
}
vector<pair<long long int,int> > zap;
for(int i=0;i<q;i++)
{
long long int x; cin>>x;
zap.push_back({x,i});
}
sort(zap.begin(),zap.end());
int wsk=-1;
for(int i=0;i<q;i++)
{
k=zap[i].first;
k-=n;
long long int lo,hi;
lo=0;
hi=m-1;
while(lo+1<hi)
{
long long int mid=(lo+hi)/2;
if(czy(mid)) lo=mid;
else hi=mid;
}
long long int res;
if(czy(hi)) res=hi;
else res=lo;
//cout<
// prefix[0...res] jest ROWNY;
long long kappa=xd[res].first;
kappa*=(res+1);
kappa-=ile(0,res);
k-=kappa;
long long int idx=(k%(res+1));
if(idx==0) idx+=res+1;
while(wsk+1<=res)
{
wsk++;
add(xd[wsk].second,1);
}
ans[zap[i].second]=kty(idx);
}
for(int i=0;i<q;i++) cout<<ans[i]<<"\n";
return 0;
}