1001,1006,1011
把后导零去掉之后,最大的那个数字一定是可以不动的(需要想一下),然后枚举a,b,c是否不动,设ta,tb,tc为a,b,c变动后的结果。
当c不动的时候,c的高位或次高位一定和ta或者tb高位对齐,枚举这四种清空。
当a不动的时候,a的最高位一定和c的最高位或者次高位对齐,枚举一下。
b和a同理。
#include
#define ll long long
using namespace std;
const ll mod = 1e9 + 7;
ll n, m;
bool pd(string& s, string& a){//a是否可以在s里面
for(int i = 0; i < s.size(); ++i){
if(i < a.size()) {
if(s[i] != a[i]) return false;
}
else if(s[i]!='0') return false;
}
return true;
}
string a, b, c, ta, tb, tc, temp;
string sub(string str1,string str2)
{
int len1=str1.size();
int len2=str2.size();
int jw=0,i,j;
for(i=len1-1,j=len2-1;i>=0&&j>=0;i--,j--)
{
int num1=str1[i]-'0';
int num2=str2[j]-'0';
num1+=jw;
if(num1-num2<0)
{
str1[i]=char('0'+10+num1-num2);
jw=-1;
}
else
{
str1[i]=char('0'+num1-num2);
jw=0;
}
}
for(i;i>=0;i--)
{
int num1=str1[i]-'0';
num1+=jw;
if(num1>=0)
{
str1[i]=char('0'+num1);
jw=0;
}
else
{
str1[i]=char('0'+10+num1);
jw=-1;
}
}
int biao=-1;
string re;
for(int i=0;i<len1;i++)if(str1[i]!='0'){biao=i;break;}
if(biao==-1)return "0";
for(int i=biao;i<len1;i++)re+=str1[i];
return re;
}
int x, y ,z;
int dx, dy, dz;
int fnd;
void sol(string &a1, string &a2, string &a3, int &x1, int &y1){//a1不动,凑a3
int len1 = a1.size(), len2 = a2.size(), len3 = a3.size();
if(len1 < len2 || len1 < len3) return;//
if(len1 == len2 && a1 < a2) return;
if(len1 == len3 && a1 <= a3) return;
tc = c;
//和c对齐
for(int i = 0; i < len1-len3; ++i) tc += "0";
if(a1 < tc){
temp = sub(tc, a1);
if(pd(temp, a2)){
fnd = 1; x1 = 0; y1 = temp.size() - a2.size(); z = len1-len3;return;
}
}
//和c次位对齐
while(tc.size() < len1+1) tc += "0";
temp = sub(tc, a1);
if(pd(temp, a2)){
fnd = 1; x1 = 0; y1 = temp.size() - a2.size(); z = len1-len3+1;
}
}
void pro(string &t, int& d){
int i;
for(i = t.size()-1; i >= 0; --i) if(t[i] != '0') break;
d = (i+1)-t.size();
t = t.substr(0, i+1);
return;
}
int main()
{
ios::sync_with_stdio(false);
int T;cin>>T;
while(T--){
cin>>a>>b>>c;
dx = dy = dz = 0;
pro(a, dx); pro(b, dy); pro(c, dz);
//cout<
fnd = 0;
int lena = a.size(), lenb = b.size(), lenc = c.size();
if(lenc >= lena && lenc >= lenb){//c不动
int ok = 1;
if(lenc == lena && a >= c) ok = 0;
if(lenc == lenb && b >= c) ok = 0;
if(ok){//c是最大的数
//和a次对齐
if(lenc > lena){
ta = a;
for(int i = 0; i < lenc-lena-1; ++i) ta+="0";
temp = sub(c, ta);
if(pd(temp, b)){
fnd = 1; x = lenc-lena-1; y = temp.size() - b.size(); z = 0;
}
}
//和a对齐
ta = a;
while(ta.size() < lenc) ta += "0";
if(c > ta){
temp = sub(c, ta);
if(pd(temp, b)){
fnd = 1; x = lenc-lena; y = temp.size() - b.size(); z = 0;
}
}
//和b次对齐
if(lenc > lenb){
tb = b;
for(int i = 0; i < lenc-lenb-1; ++i) tb+="0";
temp = sub(c, tb);
if(pd(temp, a)){
fnd = 1; x = temp.size() - a.size(); y = lenc-lenb-1; z = 0;
}
}
//和b对齐
tb = b;
while(tb.size() < lenc) tb+="0";
if(c > tb){
temp = sub(c, tb);
if(pd(temp, a)){
fnd = 1; x = temp.size() - a.size(); y = lenc-lenb; z = 0;
}
}
}
}
sol(a,b,c,x,y);
sol(b,a,c,y,x);
if(!fnd){
printf("-1\n");continue;
}
else{
x = x+dx; y = y+dy; z = z+dz;
int mi = min(x,y);
mi = min(mi, z);
x -= mi; y -=mi; z -= mi;
printf("%d %d %d\n", x, y, z);
}
}
}
/*
1
2 11 112
*/
题意有点绕,意思是:消灭一个数x需要x的代价,你要给n个数字分配数值,你如何分配使得分配数值的总额最小,并且消灭(n-k+1)个数字的最小代价大于m。
消灭(n-k+1)个数字的最小代价一定是最小的(n-k+1)的数字之和。那么我们只要让这个值为m+1,并且让其中最大的那个最小。平均分配即可。剩下的k-1个数字的值都是那个最大值。
#include
#define ll long long
using namespace std;
int main()
{
int T;cin>>T;
while(T--){
ll n, m, k;
scanf("%lld%lld%lld", &n, &m, &k);
ll ans = m+1;
if((m+1)%(n-k+1)==0) ans += (k-1)*(m+1)/(n-k+1);
else ans += (k-1)*((m+1)/(n-k+1) + 1);
printf("%lld\n", ans);
}
}
设dp[i]为i升级到i+1的期望花费,则 d p [ i ] = a i + ( 1 − p i ) Σ j = x i i d p [ i ] dp[i]=a_i+(1-p_i)\Sigma_{j=x_i}^{i}dp[i] dp[i]=ai+(1−pi)Σj=xiidp[i]
则 p i ∗ d p [ i ] = a i + ( 1 − p i ) Σ j = x i i − 1 d p [ i ] p_i*dp[i]=a_i+(1-p_i)\Sigma_{j=x_i}^{i-1}dp[i] pi∗dp[i]=ai+(1−pi)Σj=xii−1dp[i]
前缀和记录一下dp的累加值。然后每次查询[l,r]等于 Σ i = l r − 1 d p [ i ] \Sigma_{i=l}^{r-1}dp[i] Σi=lr−1dp[i]
#include
#define ll long long
using namespace std;
const int maxn = 5e5 + 50;
const int mod = 1e9 + 7;
void read(ll &x){
x = 0;
char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch <= '9' && ch >= '0') x = x*10 + ch - '0', ch = getchar();
return ;
}
ll qm(ll a, ll b){
ll res = 1;
while(b){
if(b&1) res = 1LL*res*a%mod;
a = 1LL*a*a%mod;
b>>=1;
}
return res;
}
int n, q;
ll dp[maxn];
ll sum[maxn];
int main()
{
int T;cin>>T;
while(T--){
scanf("%d%d", &n, &q);
dp[0] = sum[0] = 0;
for(int i = 1; i <= n; ++i){
ll r, s, x, a;
read(r); read(s); read(x); read(a);
ll p = r*qm(s, mod-2)%mod;
dp[i] = a;
dp[i] = (dp[i] + (1-p)*(sum[i-1] - sum[x-1])%mod )%mod;
dp[i] = dp[i] * qm(p, mod-2)%mod;
dp[i] = (dp[i] + mod)%mod;
sum[i] = (sum[i-1] + dp[i])%mod;
// cout<<"i:"<
}
while(q--){
ll l, r;
read(l); read(r);
ll ans = (sum[r-1] - sum[l-1])%mod;
ans = (ans + mod)%mod;
printf("%lld\n", ans);
}
}
}