题目描述
给出一个数列 A,求出一个数列B.
其中Bi 表示 数列A中 Ai 右边第一个比 Ai 大的数的下标(从1开始计数),没有找到这一个下标 Bi 就为0
输出数列B
输入描述:
第一行1个数字 n (n ≤ 10000)
第二行n个数字第 i 个数字为 Ai (0 ≤ Ai ≤ 1000000000)
输出描述:
一共一行,第 i 个数和第 i+1 个数中间用空格隔开.
示例1
输入
6
3 2 6 1 1 2
输出
3 3 0 6 6 0
说明
样例不用解释
水题,直接敲吧a…
#include
using namespace std;
const int maxn=(int)1e5+10;
int a[maxn];
int main()
{
int n,j;
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
bool flag = 1;
for (int i=1; i<=n; i++)
{
// 每输出一位以后有空格放在前面写
if(flag) flag=0;
else putchar(' ');
for (j=i+1; j<=n; j++)
{
if (a[j]>a[i])
{
printf("%d",j);
break;
}
}
if(j==n+1) printf("0");
}
cout<<endl;
return 0;
}
题目描述
你有一个长度为 n 序列 {a}(序列下标从1开始) ,每次可以从任意位置 i 花费 ai*i 的代价来把 ai 删除。
注意,删除后 ai 后面的数会依次向前补上(下标 -1 ) 。
求把整个序列删完的最小代价。
输入描述:
第一行一个整数 n ,第二行 n 个整数代表该序列。
输出描述:
一行一个整数表示删完序列的最小代价。
示例1
输入
2
3 2
输出
5
备注:
1<=n<=10^6 , |ai|<=10^7
保证答案在 (-2^64, 2^64) 范围内
大wu…整的花里胡哨,直接模拟QAQ(贪心)
删除数的时候,先删除负数,为保证ans尽可能的小,删负数的时候肯定是从后往前删除(不影响前面的负数的下标),我们发现此时负数刚好是ai * i
删完负数,正数从前往后删除即可,这样下标一直是1,代价就是正数本身。
#include
#define ll long long
using namespace std;
int main()
{
int n;
scanf("%d",&n);
ll ans=0,x;
for(int i=1; i<=n; i++)
{
scanf("%lld",&x);
ans += x<0 ? x*i : x;
}
printf("%lld\n",ans);
}
#include
using namespace std;
int i,j,n,m,t,ans,x,y,r,f,DP[300005],Q[300005];
vector<int>R[300005];
bool V[300005],T[300005];
struct node {
bool bit[300005];
}S[20];
bool cmp(node a,node b) {
for(int i=1;i<=(1<<n);i++)if(a.bit[i]!=b.bit[i])
return a.bit[i]>b.bit[i];
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=(1<<n);i++)R[i].clear(),DP[i]=V[i]=T[i]=0;
while(m--) {
scanf("%d%d",&i,&j);
R[i].push_back(j),R[j].push_back(i);
}
f=r=DP[1]=0,T[1]=V[1]=1;
for(i=0;i<R[1].size();i++) {
j=R[1][i];
DP[j]=(1<<i),T[j]=1,Q[r++]=j;
}
while(r!=f)
{
x=Q[f++],V[x]=1;
for(i=0;i<R[x].size();i++) {
j=R[x][i];
if(V[j]) continue;
DP[j]|=DP[x];
if(!T[j])T[j]=1,Q[r++]=j;
}
}
for(i=1;i<=(1<<n);i++)
for(j=0;j<n;j++)
S[j].bit[i]=(DP[i]>>j)&1;
sort(S,S+n,cmp);
for(i=1;i<=(1<<n);i++) {
for(ans=j=0;j<n;j++)if(S[j].bit[i])ans|=(1<<j);
printf("%d ",ans);
}
cout<<endl;
}
return 0;
}
输入描述:
第一行两个整数N,Q
第二行N个整数,第i个表示节点i的初始权值
接下来N-1行每行两个整数u,v,表示u和v之间存在一条树边
接下来Q行每行一个操作,格式如题目描述
输出描述:
对于每个询问操作,输出一行一个整数,表示答案在模23333后的结果
示例1
输入
5 5
0 0 0 0 0
1 2
1 3
3 4
3 5
1 1 3
1 3 7
1 4 5
1 5 6
2 1
输出
599
两个模板的结合,额外支持区间乘操作。
#include
using namespace std;
#define LL long long
#define mod 23333
int cnt, a[100005], b[100005], in[100005], out[100005];
vector<int> G[100005];
typedef struct Tree {
LL x;
LL X;
}Tree;
Tree tre[500005], lazy[500005];
void Create(int l, int r, int x)
{
int m;
lazy[x].X = 1;
if(l==r)
{
tre[x].x = b[l]%mod;
tre[x].X = (tre[x].x*tre[x].x)%mod;
return;
}
m = (l+r)/2;
Create(l, m, x*2);
Create(m+1, r, x*2+1);
tre[x].x = (tre[x*2].x+tre[x*2+1].x)%mod;
tre[x].X = (tre[x*2].X+tre[x*2+1].X)%mod;
}
void GaoX(int l, int r, int x, LL val)
{
tre[x].x = tre[x].x*val%mod;
tre[x].X = tre[x].X*val%mod*val%mod;
if(l!=r)
lazy[x].X = lazy[x].X*val%mod, lazy[x].x = lazy[x].x*val%mod;
}
void GaoAdd(int l, int r, int x, LL val)
{
tre[x].X = (tre[x].X+val*val%mod*(r-l+1)%mod+2*val*tre[x].x)%mod;
tre[x].x = (tre[x].x+val*(r-l+1))%mod;
if(l!=r) lazy[x].x = (lazy[x].x+val)%mod;
}
void Update(int l, int r, int x, int a, int b, LL c, int op)
{
int m;
if(l>=a && r<=b)
{
if(op==4) GaoAdd(l, r, x, c);
else GaoX(l, r, x, c);
return;
}
m = (l+r)/2;
if(lazy[x].X!=1)
GaoX(l, m, x*2, lazy[x].X), GaoX(m+1, r, x*2+1, lazy[x].X), lazy[x].X = 1;
if(lazy[x].x)
GaoAdd(l, m, x*2, lazy[x].x), GaoAdd(m+1, r, x*2+1, lazy[x].x), lazy[x].x = 0;
if(a<=m)
Update(l, m, x*2, a, b, c, op);
if(b>=m+1)
Update(m+1, r, x*2+1, a, b, c, op);
tre[x].x = (tre[x*2].x+tre[x*2+1].x)%mod;
tre[x].X = (tre[x*2].X+tre[x*2+1].X)%mod;
}
LL Query(int l, int r, int x, int a, int b, int op)
{
int m;
LL ans = 0;
if(l>=a && r<=b) {
if(op==1) return tre[x].x;
else return tre[x].X;
}
m = (l+r)/2;
if(lazy[x].X!=1)
GaoX(l, m, x*2, lazy[x].X), GaoX(m+1, r, x*2+1, lazy[x].X), lazy[x].X = 1;
if(lazy[x].x)
GaoAdd(l, m, x*2, lazy[x].x), GaoAdd(m+1, r, x*2+1, lazy[x].x), lazy[x].x = 0;
if(a<=m)
ans = (ans+Query(l, m, x*2, a, b, op))%mod;
if(b>=m+1)
ans = (ans+Query(m+1, r, x*2+1, a, b, op))%mod;
return ans;
}
void Sech(int u, int p)
{
int i, v;
in[u] = ++cnt;
b[cnt] = a[u];
for(i=0;i<G[u].size();i++)
{
v = G[u][i];
if(v==p) continue;
Sech(v, u);
}
out[u] = cnt;
}
int main(void)
{
int n, T, i, x, y, op;
scanf("%d%d", &n, &T);
for(i=1;i<=n;i++) scanf("%d", &a[i]);
for(i=1;i<=n-1;i++)
{
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
Sech(1, 0);
Create(1, n, 1);
while(T--)
{
scanf("%d", &op);
if(op==1) {
scanf("%d%d", &x, &y);
Update(1, n, 1, in[x], out[x], y, 4);
}
else {
scanf("%d", &x);
printf("%lld\n", Query(1, n, 1, in[x], out[x], 2));
}
}
return 0;
}
#include
using namespace std;
int n,m,V[2000005]={0},S[2000005]={0};
long long t,ans=0,a[2000005]={0};
int main()
{
int i,j,l,r;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&j),V[j]++;
for(i=1;i<=m;i++)
{
S[i]=S[i-1]+V[i];
for(j=i;j<=m;j+=i) a[j]+=V[i];
}
for(i=1; i<=m; i++)
{
a[i]+=a[i-1],t=a[i];
for(j=i; j<=m; j+=i)
{
l=j,r=min(j+i-1,m);
t+=(long long)j/i*(S[r]-S[l-1]);
}
ans^=t;
}
printf("%lld\n",ans);
return 0;
}