分析:水题,去维护一下前缀和以及后缀和就好,注意long long
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 using namespace std; 6 const int maxn=1e5+10; 7 const long long INF=1e10+10; 8 long long a[maxn],dp[maxn]; 9 int n; 10 int main() 11 { 12 int T; 13 scanf("%d",&T); 14 while(T--){ 15 memset(dp,0,sizeof(dp)); 16 scanf("%d",&n); 17 long long sum=0; 18 for(int i=1;i<=n;i++){ 19 scanf("%lld",&a[i]); 20 sum+=a[i]; 21 dp[i]=dp[i-1]+a[i]; 22 } 23 long long ans=INF; 24 int pos; 25 for(int i=1;i<=n;i++){ 26 long long num=sum+dp[i]; 27 if(num<ans){ 28 ans=num; 29 pos=i; 30 } 31 sum-=a[i]; 32 } 33 printf("%d\n",pos); 34 } 35 return 0; 36 }
分析:水题,对于个数为偶数的交换任意两个就好,对于个数为奇数的,前面交换任意两个,后三个数做两次交换
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 using namespace std; 6 const int maxn=1e5+10; 7 int T,n,a[maxn]; 8 int main() 9 { 10 int T; 11 cin>>T; 12 while(T--){ 13 cin>>n; 14 for(int i=1;i<=n;i++) 15 a[i]=i; 16 if(n%2==0){ 17 for(int i=1;i<=n;i+=2){ 18 swap(a[i],a[i+1]); 19 } 20 for(int i=1;i<n;i++){ 21 printf("%d ",a[i]); 22 } 23 printf("%d\n",a[n]); 24 }else{ 25 if(n==1){ 26 printf("%d\n",a[n]); 27 }else{ 28 for(int i=1;i<=n-3;i+=2){ 29 swap(a[i],a[i+1]); 30 } 31 swap(a[n-2],a[n-1]); 32 swap(a[n-1],a[n]); 33 for(int i=1;i<n;i++){ 34 printf("%d ",a[i]); 35 } 36 printf("%d\n",a[n]); 37 } 38 } 39 } 40 return 0; 41 }
分析:找出数列中出现过的数,然后暴力去构造A到Z就好了,注意有些数在数列中只出现过一次
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 #include "set" 6 using namespace std; 7 const int maxn=1e5+100; 8 const int maxm=200; 9 int vis[maxn],f[maxm]; 10 char s[maxn]; 11 int T; 12 int main() 13 { 14 cin>>T; 15 getchar(); 16 while(T--){ 17 memset(s,0,sizeof(s)); 18 memset(vis,0,sizeof(vis)); 19 memset(f,0,sizeof(f)); 20 int n=0; 21 char ch=getchar(); 22 while(ch!=‘\n‘) s[++n]=ch,ch=getchar(); 23 for(int i=1;i<=n;i++){ 24 int num=s[i]-‘0‘; 25 vis[num]++; 26 } 27 for(int i=0;i<=9;i++){ 28 for(int j=0;j<=9;j++){ 29 if(vis[i]&&vis[j]){ 30 if(i==j&&vis[i]==1) continue; 31 int num=i*10+j; 32 if(num>=‘A‘&&num<=‘Z‘){ 33 f[num]=1; 34 } 35 } 36 } 37 } 38 for(char i=‘A‘;i<=‘Z‘;i++) 39 if(f[i]){ 40 printf("%c",i); 41 } 42 printf("\n"); 43 } 44 return 0; 45 }
分析:非常好的一道题,感谢hzm教我怎么做,首先我们需要用线段树去维护每个操作出现的次数。这个地方首先我们倒着推,开始的时候我们初始化每个操作都执行1次,然后遇到2的时候,我们就把2所维护的区间[l,r]当中的每个数都加上当前这个操作执行的次数,这样我们可以求出每个1操作执行了多少次,最后在线段树区间修改就搞定了。
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 #include "vector" 6 using namespace std; 7 const int maxn=1e5+10; 8 const int mod=1e9+7; 9 int T,n,m; 10 struct Node 11 { 12 int num,x,y; 13 }; 14 Node p[maxn]; 15 16 17 18 //typedef long long int; 19 struct T 20 { 21 int l, r; 22 int c; 23 } tree[maxn<<2]; 24 int add[maxn<<2], mul[maxn<<2]; 25 26 void pushdown(int k, int d,int p) 27 { 28 if(mul[k]==1&&add[k]==0) 29 return ; 30 tree[k<<1].c=tree[k<<1].c*mul[k]%p; 31 tree[k<<1|1].c=tree[k<<1|1].c*mul[k]%p; 32 tree[k<<1].c=(tree[k<<1].c+add[k]*(d-(d>>1)))%p; 33 tree[k<<1|1].c=(tree[k<<1|1].c+add[k]*(d>>1))%p; 34 mul[k<<1]=mul[k]*mul[k<<1]%p; 35 mul[k<<1|1]=mul[k]*mul[k<<1|1]%p; 36 add[k<<1]=(add[k<<1]*mul[k]+add[k])%p; 37 add[k<<1|1]=(add[k]+add[k<<1|1]*mul[k])%p; 38 add[k]=0; 39 mul[k]=1; 40 return ; 41 } 42 void pushup(int k,int p) 43 { 44 tree[k].c=(tree[k<<1].c+tree[k<<1|1].c)%p; 45 } 46 void build1(int l, int r, int k, int p) 47 { 48 tree[k].l=l; 49 tree[k].r=r; 50 tree[k].c=0; 51 mul[k]=1; 52 add[k]=0; 53 if(l==r) 54 { 55 tree[k].c=1; 56 return; 57 } 58 int mid=(tree[k].l+tree[k].r)>>1; 59 build1(l, mid, k<<1, p); 60 build1(mid+1,r,k<<1|1, p); 61 pushup(k, p); 62 } 63 void build0(int l, int r, int k, int p) 64 { 65 tree[k].l=l; 66 tree[k].r=r; 67 tree[k].c=0; 68 mul[k]=1; 69 add[k]=0; 70 if(l==r) 71 { 72 tree[k].c=0; 73 return; 74 } 75 int mid=(tree[k].l+tree[k].r)>>1; 76 build0(l, mid, k<<1, p); 77 build0(mid+1,r,k<<1|1, p); 78 pushup(k, p); 79 } 80 void update(int l, int r, int k, int c, int op, int p) 81 { 82 if(tree[k].l>=l&&tree[k].r<=r){ 83 if(op==1){ 84 add[k]=add[k]*c%p; 85 mul[k]=mul[k]*c%p; 86 tree[k].c=tree[k].c*c%p; 87 } 88 else{ 89 add[k]=(add[k]+c)%p; 90 tree[k].c=(tree[k].c+(tree[k].r-tree[k].l+1)*c)%p; 91 } 92 return; 93 } 94 pushdown(k, tree[k].r-tree[k].l+1, p); 95 int mid=(tree[k].l+tree[k].r)>>1; 96 if(l<=mid) 97 update(l,r,k<<1,c,op,p); 98 if(r>mid) 99 update(l,r,k<<1|1,c,op,p); 100 pushup(k,p); 101 } 102 int query(int l, int r, int k, int p) 103 { 104 if(tree[k].l>=l&&tree[k].r<=r) 105 return tree[k].c%p; 106 pushdown(k, tree[k].r-tree[k].l+1, p); 107 int ans=0; 108 int mid = (tree[k].l+tree[k].r)>>1; 109 if(l<=mid) 110 ans=(ans+query(l,r,k<<1,p))%p; 111 if(r>mid) 112 ans=(ans+query(l,r,k<<1|1, p))%p; 113 return ans%p; 114 } 115 116 vector<int> Q; 117 int dp[maxn]; 118 int main() 119 { 120 cin>>T; 121 while(T--){ 122 memset(dp,0,sizeof(dp)); 123 scanf("%d%d",&n,&m); 124 int N=max(n,m); 125 Q.clear(); 126 build1(1,N,1,mod); 127 for(int i=1;i<=m;i++){ 128 scanf("%d%d%d",&p[i].num,&p[i].x,&p[i].y); 129 if(p[i].num==1){ 130 Q.push_back(i); 131 } 132 } 133 if(Q.size()==m){ 134 build0(1,N,1,mod); 135 for(int i=1;i<=m;i++){ 136 update(p[i].x,p[i].y,1,1,2,mod); 137 } 138 for(int i=1;i<n;i++) 139 printf("%d ",query(i,i,1,mod)); 140 printf("%d\n",query(n,n,1,mod)); 141 continue; 142 } 143 if(Q.size()==0){ 144 for(int i=1;i<n;i++) 145 printf("0 "); 146 printf("0\n"); 147 continue; 148 } 149 for(int i=m;i>=1;i--){ 150 if(p[i].num==1){ 151 continue; 152 }else{ 153 int res=query(i,i,1,mod); 154 update(p[i].x,p[i].y,1,res,2,mod); 155 } 156 } 157 for(int i=0;i<Q.size();i++){ 158 dp[Q[i]]=query(Q[i],Q[i],1,mod); 159 //printf("%d ",dp[Q[i]]); 160 } 161 //printf("\n"); 162 build0(1,N,1,mod); 163 for(int i=0;i<Q.size();i++){ 164 int tt=Q[i]; 165 int num=dp[tt]; 166 //cout<<tt<<endl; 167 //cout<<num<<endl; 168 update(p[tt].x,p[tt].y,1,num,2,mod); 169 //add1(p[tt].x,num); 170 //add1(p[tt].y+1,-num); 171 } 172 for(int i=1;i<n;i++) 173 printf("%d ",query(i,i,1,mod)); 174 printf("%d\n",query(n,n,1,mod)); 175 } 176 return 0; 177 }
时间: 2024-10-29 19:10:34