A:
- 考慮按掃描線的順序處理對一個詢問有貢獻的修改,用數據結構維護出現的時間以及 −1,+1,問題即從一個時間向前第一個爲 k 的時間,那麼我們維護後綴 max 即可二分,O(npoly(logn))
#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
namespace IO{
cs int Rlen=1<<22|1;
inline char gc(){
static char buf[Rlen],*p1,*p2;
(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));
return p1==p2?EOF:*p1++;
} int read(){
int x=0; char c=gc(); bool f=false;
while(!isdigit(c)) f=c=='-', c=gc();
while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();
return f?-x:x;
}
} using namespace IO;
cs int N = 2e5 + 50;
cs int INF = 1e9 + 7;
typedef pair<int, int> pi;
int n, m, a[N], b[N];
vector<pi> qry[N];
struct dat{ int typ, op, c; };
vector<dat> mf[N]; int as[N];
namespace SGT{
cs int N = ::N << 2;
#define mid ((l+r)>>1)
pi vl[N];
pi operator + (cs pi &a, cs pi &b){
return mp(a.fi+b.fi, max(b.se, a.se+b.fi));
}
void up(int x){ vl[x] = vl[x<<1] + vl[x<<1|1]; }
void ins(int x, int l, int r, int p, int v){
if(l==r) return vl[x]=mp(v,v), void();
(p<=mid)?ins(x<<1,l,mid,p,v):ins(x<<1|1,mid+1,r,p,v); up(x);
}
pi qry(int x, int l, int r, int L, int R){
if(L<=l&&r<=R) return vl[x];
if(R<=mid) return qry(x<<1,l,mid,L,R);
if(L>mid) return qry(x<<1|1,mid+1,r,L,R);
return qry(x<<1,l,mid,L,R) + qry(x<<1|1,mid+1,r,L,R);
}
#undef mid
}
int work(int k, int t){
int l=1, r=t;
if(SGT::qry(1,1,m,1,t).se<k) return -1;
while(l<r){
int mid=(l+r+1)>>1;
if(SGT::qry(1,1,m,mid,t).se>=k) l=mid;
else r=mid-1;
} return a[l];
}
int main(){
#ifdef FSYolanda
freopen("stack6.in","r",stdin);
#endif
n=read(), m=read();
static bool vs[N];
for(int i=1,op,l,r; i<=m; i++){
op=read(), l=read(), r=read();
if(op==1) a[i]=read();
if(op==3){
qry[l].pb(mp(r,i));
vs[i] = true; continue;
} op = op==1 ? 1 : -1;
mf[l].pb((dat){op,1,i});
mf[r+1].pb((dat){op,-1,i});
}
for(int i=1; i<=n; i++){
for(int e=0; e<mf[i].size(); e++){
dat x = mf[i][e];
if(x.op == -1) SGT :: ins(1,1,m,x.c,0);
else SGT :: ins(1,1,m,x.c,x.typ);
} for(int e=0; e<qry[i].size(); e++){
pi x = qry[i][e];
as[x.se] = work(x.fi,x.se);
}
}
for(int i=1; i<=m; i++) if(vs[i]){
if(~as[i]) cout << as[i] << '\n';
else puts("Error");
} return 0;
}
B
- min25 即可,O(lognn3/4)
#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
typedef long long ll;
cs int N = 1e5 + 50;
int prm[N], pc; bool isp[N];
int T, n, S;
void linear_sieve(int n){
pc=0; for(int i=2; i<=n; i++){
if(!isp[i]) prm[++pc]=i;
for(int j=1; j<=pc; j++){
if(prm[j]*i>n) break;
isp[prm[j]*i]=true; if(i%prm[j]==0) break;
}
}
}
int A[N], B[N], vl[N], nd; ll f[N];
int idx(int x){ return x<=S?A[x]:B[n/x]; }
ll work(int x, int n){
if(n<=1||n<prm[x]) return 0;
ll as = f[idx(n)] - (x-1) * 3ll;
for(int i=x; i<=pc; i++){
if(prm[i]*prm[i]>n) break;
for(int e=1,t=prm[i];(ll)t*prm[i]<=n;t*=prm[i],++e){
as += work(i+1,n/t) * (2ll*e+1);
as += 2ll*(e+1)+1;
}
} return as;
}
void Main(){
scanf("%d",&n); linear_sieve(S=sqrt(n));
nd=0; for(int l=1,r; l<=n; l=r+1){
int v=n/l; r=n/v;
if(v<=S) A[v]=++nd;
else B[n/v]=++nd; vl[nd]=v;
} for(int i=1; i<=nd; i++) f[i]=3ll*(vl[i]-1);
for(int i=1; i<=pc; i++)
for(int j=1; j<=nd; j++){
if(prm[i] * prm[i] > vl[j]) break;
int t = idx(vl[j]/prm[i]);
f[j] -= f[t]-3ll*(i-1);
} cout << work(1,n)+1 << '\n';
}
int main(){
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
scanf("%d",&T);
while(T--) Main(); return 0;
}
C
- 考慮最大化的時候有一個取到端點,這個可以通過旋轉卡殼得到
- 最小化的時候考慮兩條對邊,若平行可以簡單計算答案,若不平行,將兩條線延長求交點,考慮夾角爲定值,面積爲定值,最小化底邊長度,那麼一定是等腰三角形,即 absinα=C,minimize(a2+b2−2abcosα),同樣可以簡單計算答案,O(n)
#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
namespace IO{
cs int Rlen=1<<22|1;
inline char gc(){
static char buf[Rlen],*p1,*p2;
(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));
return p1==p2?EOF:*p1++;
} int read(){
int x=0; char c=gc(); bool f=false;
while(!isdigit(c)) f=c=='-', c=gc();
while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();
return f?-x:x;
}
} using namespace IO;
cs int N = 5e3 + 50;
double eps = 1e-10;
double INF = 1e18;
int sgn(double a){ return (a>eps)-(a<-eps); }
struct pnt{
double x, y; pnt(double _x=0, double _y=0){ x=_x; y=_y; }
void input(){ x=read(), y=read(); }
void output(){ cout<<x<<" "<<y<<'\n'; }
pnt operator + (cs pnt &a){ return pnt(x+a.x, y+a.y); }
pnt operator - (cs pnt &a){ return pnt(x-a.x, y-a.y); }
double operator * (cs pnt &a){ return x * a.y - y * a.x; }
pnt operator * (cs double &a){ return pnt(x*a, y*a); }
double len(){ return sqrt(x * x + y * y); }
void norm(){ double t = len(); x = x / t; y = y / t; }
};
#define idx(x) (x>n?x-n:x)
int n; pnt a[N];
double S, A, B;
double dis(pnt a, pnt b){ return (b - a).len(); }
double calc(pnt a, pnt b, pnt c){
double k = fabs((b-a) * (c-a));
return k / dis(b,c);
}
pnt crs(pnt a, pnt b, pnt c, pnt d){
double S1=(c-a)*(d-a), S2=(c-b)*(d-b);
assert(sgn(S1-S2));
return a + (b-a) * (S1/(S1-S2));
}
double ang(pnt a, pnt b){
return asin(fabs(a*b)/(a.len()*b.len()));
}
void work_mx(){
double now = 0;
for(int i=1,j=1; i<=n; i++){
if(j<=i) j=i+1, now = a[i] * a[idx(i+1)];
while(true){
if(now + (a[idx(j)] * a[i]) > S) break;
now += a[idx(j)] * a[idx(j+1)]; ++j;
} double nS = now + a[idx(j)] * a[i] - S;
double d = calc(a[i],a[idx(j-1)],a[idx(j)]);
double len = nS / d; pnt dir = a[idx(j-1)] - a[idx(j)];
dir.norm(); dir = dir * len; pnt t = a[idx(j)] + dir;
A = max(A, dis(a[i],t));
B = min(B, dis(a[i],t)); now -= a[i] * a[i+1];
}
}
void work_mn(){
double now = 0;
for(int i=1,j=1; i<=n; i++){
if(j<=i) j=i+1, now = a[i] * a[idx(i+1)];
while(true){
if(now + (a[idx(j)] * a[i]) > S) break;
now += a[idx(j)] * a[idx(j+1)]; ++j;
} double nS = now + a[idx(j)] * a[i] - S;
pnt dx = a[i] - a[i+1], dy = a[idx(j)] - a[idx(j-1)];
if(!sgn(dx * dy)){
double d = calc(a[i],a[idx(j-1)],a[idx(j)]);
int len = min(dis(a[i],a[i+1]), dis(a[idx(j)],a[idx(j-1)]));
if(nS <= d * len) B = min(B, d);
} else{
pnt v = crs(a[i+1],a[i],a[idx(j-1)],a[idx(j)]);
int x = i, y = idx(j), tx = i+1, ty = idx(j-1);
if(sgn((a[i]-v) * (a[idx(j)]-v)) < 0) swap(x,tx), swap(y,ty), nS = S;
nS = nS + fabs((a[x]-v) * (a[y]-v));
double an = ang(a[x]-v, a[y]-v);
double len = sqrt(nS/sin(an));
double l1=(a[x]-v).len(), r1=l1+dis(a[x],a[tx]);
double l2=(a[y]-v).len(), r2=l2+dis(a[y],a[ty]);
if(max(l1,l2)<=len && len<=min(r1,r2))
B = min(B, sqrt(2*nS/sin(an)*(1-cos(an))));
} now -= a[i] * a[i+1];
}
}
int main(){
#ifdef FSYolanda
freopen("1.in","r",stdin);
#endif
n=read();
for(int i=1; i<=n; i++) a[i].input(); a[n+1] = a[1];
for(int i=1; i<=n; i++) S += a[i] * a[i+1];
S = S * 0.5; B = INF; work_mx(), work_mn();
printf("%.8lf\n%.8lf",B,A); return 0;
}