水题,贪心,一个灯亮两个格子就行,所以就是 (m*n+1)>>1
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL N=12;
int main(int argc, char const *argv[])
{
// #define DEBUG
#ifdef DEBUG
freopen("1.dat","r",stdin);
freopen("ans.dat","w",stdout);
#endif
LL _;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>_;
while(_--){
LL a,b;
cin>>a>>b;
cout<<((a*b+1)>>1)<<endl;
}
return 0;
}
贪心,直接一次把能叫的最多人叫去,排序后做就行
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL N=1e5+10;
int a[N];
int main(int argc, char const *argv[])
{
// #define DEBUG
#ifdef DEBUG
freopen("1.dat","r",stdin);
freopen("ans.dat","w",stdout);
#endif
LL _;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>_;
while(_--){
int n;
cin>>n;
rep(i,0,n)
cin>>a[i+1];
sort(a+1,a+n+1);
int ans = 1; //自己
int i=n;
while(i>0&&a[i]>i)
i--;
ans += i;
cout<<ans<<endl;
}
return 0;
}
观察后可以发现,所有不同的值最后是连续的,因为每提前向下一次,比往右一次收益大1
所以可以求最大值和最小值,看之间共多少数,但是直接猜了个差距相乘加1就对了,迷惑。
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
int main(int argc, char const *argv[])
{
// #define DEBUG
#ifdef DEBUG
freopen("1.dat","r",stdin);
freopen("ans.dat","w",stdout);
#endif
LL _;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>_;
while(_--){
LL x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
LL gapx = x2-x1;
LL gapy = y2-y1;
cout<<gapy*gapx+1<<endl;
}
return 0;
}
观察可以发现,使得结束日期在一个月的末尾,收益最高
所以求前缀和之后二分起点就可以
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL N=2e5+10;
LL a[2*N];
LL b[2*N];
LL c[N];
int main(int argc, char const *argv[])
{
// #define DEBUG
#ifdef DEBUG
freopen("1.dat","r",stdin);
freopen("ans.dat","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
LL n,x;
cin>>n>>x;
rep(i,0,n) cin>>c[i];
a[0]=c[0];
b[0]=((c[0]+1)*c[0])>>1;
rep(i,1,2*n){
b[i] = (((c[i%n]+1)*c[i%n])>>1)+b[i-1];
a[i] = c[i%n]+a[i-1]; //计算天数
}
//如果我在某个月到,那么应该选择哪个月呢
LL ans = 0;
rep(i,0,n){ //在这个月的终点结束
LL l = i;
LL r = i+n;
LL temp = r;
while(r>=l){
LL mid = (l+r)>>1;
if(a[i+n]-a[mid]>=x){
l = mid+1;
}else{
temp = mid;
r = mid-1;
}
}
LL cnm = x-(a[i+n]-a[temp]);
// cout<<cnm<<" "<<i+n<<" "<<temp<<endl;
LL rem = ((c[temp%n]+1)*c[temp%n])>>1;
rem -= ((c[temp%n]-cnm+1)*(c[temp%n]-cnm))>>1;
// cout<<rem<<endl;
// cout<<b[i+n]-b[temp]<<endl;
ans = max(ans,b[i+n]-b[temp]+rem);
}
cout<<ans<<endl;
return 0;
}